Moved ~/.local/share/steam. Ran steam. It deleted everything on system owned by user. #3671

Open
keyvin opened this Issue Jan 14, 2015 · 221 comments

Projects

None yet
@keyvin
keyvin commented Jan 14, 2015

Edit: Please stop posting stupid image memes or unhelpful messages. This interferes with Valve's ability to sift through the noise and see if anyone can figure out what triggers it.

This may not be a common problem because I change all sorts of configuration about my system. The script in question does something in a really, really stupid way, but it probably doesn't trigger the fail scenario for every system because...

Original Bug:
I am not sure what happened. I moved the folder in the title to a drive mounted under /media/user/BLAH and symlinked /home/user/.local/steam to the new location.

I launched steam. It did not launch, it offered to let me browse, and still could not find it when I pointed to the new location. Steam crashed. I restarted it.

It re-installed itself and everything looked great. Until I looked and saw that steam had apparently deleted everything owned by my user recursively from the root directory. Including my 3tb external drive I back everything up to that was mounted under /media.

Everything important, for the most part, was in the cloud. It is a huge hassle, but it is not a disaster. If there is the chance that moving your steam folder can result in recursively deleting everything in the directory tree you should probably just throw up an error instead of trying to point to other stuff. Or you know, allow the user to pick an install directory initially like on windows.

My system is ubuntu 14.04, and the drive I moved it to was ntfs if its worth anything.

@doofy
doofy commented Jan 15, 2015

I am impressed how calm you stay about this. This is terrible. I just lost my home directory. All i did was start steam.sh with STEAM_DEBUG=1. I will investigate this and report back.

edit1: I suspect steam.sh got some bugs(does not check own variables) and when it tried to do scary things it crapped himself.
Line 468: rm -rf "$STEAMROOT/"*

edit2: It gets better. Seems on windows Steam is overeager too! https://support.steampowered.com/kb_article.php?ref=9609-OBMP-2526 (The warning part is interesting. Because everybody reads this before uninstalling...)

@Tele42
Tele42 commented Jan 15, 2015

I agree, that line minimally requires an exists and not null check for $STEAMROOT

@keyvin
keyvin commented Jan 15, 2015

#scary!

As an ex programmer, that really makes me chuckle. Can I at least get an apology from whoever committed that comment without adding a fix?

@onodera-punpun

This also happened to me a few weeks ago, my entire home was deleted by the steam.sh script.

@pythoneer

introduced here Sep 10, 2013 indrora/steam_latest@21cc141 line 359

rm -rf "$STEAMROOT/"* could be evaluated as rm -rf "/"* if $STEAMROOT is empty

but what exactly caused this? i've symlinked ~/.local/share/steam to, so i am a bit afraid to start steam :/

@TcM1911
TcM1911 commented Jan 15, 2015

pythoneer,

I believe the issue starts on line 19:

# figure out the absolute path to the script being run a bit
# non-obvious, the ${0%/*} pulls the path out of $0, cd's into the
# specified directory, then uses $PWD to figure out where that
# directory lives - and all this in a subshell, so we don't affect
# $PWD

STEAMROOT="$(cd "${0%/*}" && echo $PWD)"
STEAMDATA="$STEAMROOT"

This probably returns as empty which mean: rm -rf "$STEAMROOT/"* is the same ass rm -rf "/"*.

@pythoneer

TcM1911,

that's my guess, too.

@minio
minio commented Jan 15, 2015

@keyvin @d00fy :
Line proceeded by # Scary! comment is in reset_steam() function, which is executed if and only if steam.sh is invoked with --reset as first argument.

Did any of you deliberately invoked that script with that option? If yes, why did you do it? What were you trying to achieve?

Removing user data is obviously wrong, no doubt about it. But if this happens only when user requests certain action, scope of that issue is somewhat limited.

@jthill
jthill commented Jan 15, 2015

Yeah, they kinda need a readlink in there.

STEAMROOT=$(readlink -nf "${0%/*}")
@jthill
jthill commented Jan 15, 2015

@Minio Not "only if". reset_steam is also invoked by removing your .steam directory, since that sets INITIAL_LAUNCH

@soren121

@Minio A script accidentally running rm -rf /* is unacceptable in any scenario.

@gtmanfred

it is like bumblebee all over again!
MrMEEE/bumblebee-Old-and-abbandoned#123

@Plaque-fcc

I encountered Steam behaviour like with Β«--resetΒ» for several times:
when I added Β«--resetΒ» AND when I didn't. So β€” not Β«only ifΒ», can
confirm this, even having not deleted ~/.steam/ dir, too.

@prometheanfire

wonder what the code path is to hit that rm without --reset

@indrora
indrora commented Jan 15, 2015

Can confirm; I have Steam bounded in an SELinux context ("Steam") and SELinux spits out:

Context violation: process /home/indrora/.local/share/Steam/ubuntu12_32/steam is only allowed in context steam_context, attempted to remove /boot/efi/grub/efistub

Ooops. I'll write a patch and PR it 🍺

@johnv-valve johnv-valve self-assigned this Jan 15, 2015
@johnv-valve
Member

Does anybody have reliable repro steps for this? I can easily add the checks for STEAMROOT being empty, but I would also like to fix the root cause if possible.

@rcxdude
rcxdude commented Jan 15, 2015

It will definitely fail if you run steam.sh as bash steam.sh. I don't know if that's the cause in this case. In terms of root cause, I would say you should use set -e, set -u, and similar options in order to make the script less likely to silently ignore errors.

@ayust
ayust commented Jan 15, 2015

Using ${STEAMROOT:?} instead of $STEAMROOT would have helped, too.

(For those not familiar, ${FOO:?} is identical to $FOO except that it errors out automatically if $FOO is empty or unset.)

@ju2wheels

Which is the same thing that would have happened had the unnecessary '/*' not been there anyway, it would have errored out. Its not necessary because the rm was set to recursive already...

if [ ! -z "${STEAMROOT}" ]; then
   rm -rf "${STEAMROOT}"
fi
@rcxdude
rcxdude commented Jan 16, 2015

Here is a patch which enables set -e, set -u, and a few others, and then fixes up all the places where undefined variables are expected to be (as far as I can tell): https://gist.github.com/rcxdude/1f6257e0a965147a462c

@mablae
mablae commented Jan 16, 2015

@rcxdude Come on. We are on github here. Do that in a PR please! Do not post whole patch files into issues... πŸ‘Ž

@dannyfallon

@mablae There is no code on this repo, there is nothing to send in a PR against. A gist wouldn't have gone astray though πŸ˜„

@slnovak
slnovak commented Jan 16, 2015

@rcxdude: Please link to a Gist.

@sdt16
sdt16 commented Jan 16, 2015

@mablae How about instead of being a jerk, you link @rcxdude to some documentation.

@Tele42
Tele42 commented Jan 16, 2015

@johnv-valve regardless of tracking down the cause of this, this rm line must be protected from future accidental gremlins due to the severity of the fail scenario.

@mablae
mablae commented Jan 16, 2015

@dannyfallon Oh, sorry then...
@sdt16 I am sorry. Thought the code was on this repo ... Didn't wanted to be a "jerk" :)

@Wapaca
Wapaca commented Jan 16, 2015

Does it happen only if you move ~/.local/share/steam ? #scary! :s

@joshenders

The idiomatic way to do this in Bash is to use default variables as in ,"${var:-/sane/path}" or "${var:?}" as was already mentioned. While using set -u or similar could have prevented this mistake, it's lazy and considered bad style.

@doofy
doofy commented Jan 16, 2015

If steam really wants to act like a package manager it should only delete files created by itself.

@soren121 +1

@ryenus
ryenus commented Jan 16, 2015

Shell scripts can also have tests, see shunit2. I wish I used it instead of making mini/naive one myself.

@damm
damm commented Jan 16, 2015

it's 2015; I think we can do better than complex badly written shell scripts.

rm is dangerous; you should never use rm ${macro}/

@mpnordland

@d00fy Steam is essentially a package manager for your games.

@carlosmcevilly

@ju2wheels your snippet has a spurious 'D' in it, 'STEAMROOT' versus 'STEAMDROOT' -- so ${STEAMDROOT} will be empty and that code is going to end up starting at the current directory and doing a recursive delete from there.

Could be almost as bad depending what the current directory is. Let's hope nobody copy/pastes that snippet for actual use.

@soren121

@mpnordland I think that's what he said.

@neko
neko commented Jan 16, 2015

Is this the new bumblebee?

@nhuerta
nhuerta commented Jan 16, 2015

I hope no one is running this as root

@hakusaro

@d00fy I'm going to make the argument that while Steam is certainly at fault, you should definitely be using off site backups for this exact reason.

@DanielGibson

I hope no one is running this as root

On a typical desktop Linux system that would only make it marginally worse - reinstalling the OS is less of a problem than losing all your data from $HOME

@keyvin
keyvin commented Jan 16, 2015

@john-valve You are more than welcome to any log files that a data recovery service can get from the drive, as long as you give me a copy of everything. I do not have a large drive to undelete to, so the data that wasn't in the cloud is. Mad props for #Scary though

@nicatronTg Yes, I should need to have a complete back up rotation of dailies, four weeklies, and 12 monthlies so that I can feel safe and secure running steam for linux.

@nhuerta
nhuerta commented Jan 16, 2015

@DanielGibson Sure, as long as you didn't mount other partitions rw somewhere else

@ju2wheels

@carlosmcevilly even if they did it would be better than the existing code thats there ;-) , it will just fail and not take the world with it. But.... but... i fixed my typo ;-) , thx.

@RamchandraApte

Hmm.. when I was copying .steam from an older installation to a newer installation of Kubuntu, I saw in stdout messages like "running rm -rf " when I was running it (after the rm -rf it installed Steam again with the 200MB download). Though of course I didn't lose any data.

@keyvin This is somewhat OT but to recovery your data, immediately stop using the external drive and run something like PhotoRec or TestDisk or if the drive has important files you can even use a program like ddrescue to copy the drive. If you haven't used the drive since the data loss then most of your data should be recoverable.

@pixelb
pixelb commented Jan 16, 2015

Note there is also protection against this within GNU rm itself. I.E. this would have protected the / dir at least:

rm -rf "$STEAMROOT/" && mkdir "$STEAMROOT"

But it's best leave out the / in any case as it's redundant

rm -rf "$STEAMROOT" && mkdir "$STEAMROOT"
@seanchannel

Bash-isms are the problem here:

(cd `dirname $0`; STEAMROOT=`pwd`)

If dirname and pwd aren't in your "$PATH" then fuck you.

@hachre
hachre commented Jan 16, 2015

My condolences, @keyvin. I lost all my data like this in 1998 due to a SuSE Linux installation script having exactly this bug in it as well. Back then I lost my Linux, my Windows, and all my data and I only learned what backups are really for from that incident...

@michaelsbradleyjr

@TcM1911 Determining the path of the script being invoked, in a fully portable (w.r.t. platforms) and completely reliable manner, even in the face of symlinks, is a tricky problem and all too easy to get wrong. The only bullet proof way of doing it, of which I'm aware, is provided below (assumes bash); could be prepended to any script needing this functionality.

#!/bin/bash

script_path () {
    local scr_path=""
    local dir_path=""
    local sym_path=""
    # get (in a portable manner) the absolute path of the current script
    scr_path=$(cd -P -- "$(dirname -- "$0")" && pwd -P) && scr_path=$scr_path/$(basename -- "$0")
    # if the path is a symlink resolve it recursively
    while [ -h $scr_path ]; do
        # 1) cd to directory of the symlink
        # 2) cd to the directory of where the symlink points
        # 3) get the pwd
        # 4) append the basename
        dir_path=$(dirname -- "$scr_path")
        sym_path=$(readlink $scr_path)
        scr_path=$(cd $dir_path && cd $(dirname -- "$sym_path") && pwd)/$(basename -- "$sym_path")
    done
    echo $scr_path
}

script_dir=$(dirname -- "$(script_path)")
@MrSchism
Member

@sindresorhus I'd disagree with using trash instead of rm because having to rely on node just adds complexity to systems that wouldn't otherwise need node.

It's also worth mentioning that most of the linux distros I've used recently have the --preserve-root flag already available...

@tute tute referenced this issue in coreyleveen/super-pry.io Jan 16, 2015
Merged

Add warning note about security risks #1

@sindresorhus

I'd disagree with using trash instead of rm because having to rely on node just adds complexity to systems that wouldn't otherwise need node.

I know people disagree with that. That's fine. I was linking to the safeguard rm section.

@paranoidsp

I've moved my directory and symlinked it too, and I've thankfully not had such issues before. Regardless, as someone mentioned before, I'd strongly suggest adding test cases against such major bugs.

@albertvaka

This big companies are so in the need of engineers that would even hire my grandma, and then shit happens.

@Strubbl
Strubbl commented Jan 16, 2015

In this context, how can i remove steam from my Linux without using steam?

@skybert
skybert commented Jan 16, 2015

As @d00fy said, it's amazing how calm you were about this, @keyvin. A great bug report it was too. Embarrassing as bugs like these are, it's a lot easier to take it on with reports like this one.

As others have pointed out too, this is an excellent bug for advocating using some BASH-strictness, I like to use this:

set -euo pipefail

This bug is also a good case for advocating TDD with shunit2. Make the steam script modular so that parts of it can be (unit) tested, write a test for this bug which fails and then fix it. We all do this in other "real" programming languages and there's no reason why we can't do this in BASH too. Hooking it up with CI servers like Jenkins is no problem either.

@darklajid

Tangentially related:

I assume all the people that moved this folder are running out of disk space/want to stuff the files elsewhere. Like myself. This is what I did on Windows just a couple days ago, I'd hope that Steam on Linux supports the same (hidden) option: http://www.rockpapershotgun.com/2012/09/11/finally-an-in-built-way-to-choose-steam-install-locations/

Basically:

  • Close Steam
  • Run steam -dev
  • Click on the new 'Console' tab
  • Enter 'install_folder_ui' (you even get tab completion)
  • Add a new path, say .. /media/steam
  • Close steam, restart without -dev

Now you can pick the location during installation ("This game? Install to my SSD. That? Ah, large slow disk is fine"). You can also move games between locations (from $path1/SteamApps/common to $path2/SteamApps/common and that will 'just work' in nearly all cases).

So, maybe Valve should make that more accessible in the UI, bypassing the need of users to mess with the default install path?

@lodyb
lodyb commented Jan 16, 2015

Thanks for reminding me to always check shell scripts before executing them

@synapse84

@darklajid changing the destination can already be done without using -dev, console, and install_folder_ui.

steam -> settings -> downloads -> steam library folders

@darklajid

@synapse84 Whoa - and here I kept that bookmark around, treasuring my knowledge of hidden options. :) Thanks a lot!

@woctezuma

Amazingly scary.

@ohjames
ohjames commented Jan 16, 2015

Stupidest bug I've seen in years.

@victoredwardocallaghan

git blame on that, who did the commit?

Valve is retarded on so many levels, they completely screw up how libraries are linked up in some vain attempt to make Linux a kind of Ubuntu ABI stable distro. Now this.. The fact that steam is not using chroot and Linux kernel namespace support to protect against buggy/nefarious applications is idiotic security practice.

Further, what is Valve doing for a proper review and audit system for patchsets and continues integration, github comments, is that it.. F* may as well write software via Stasi-book (Facebook) wall posts lol..

@stryju
stryju commented Jan 16, 2015

I just wanted, on behalf of whole internet, to tell that the whole world could learn a thing or two from you
@keyvin.
The "tone" used to describe the issue is informative and polite, raging, straight to the point.
well done!

🍻

@Bumrang
Bumrang commented Jan 16, 2015

This is Bumblebee all over again.

@xtraeme
xtraeme commented Jan 16, 2015

Dear Valve Software,

this is one of the greatest fails I've seen in a long while, only compared to the #GotoFail issue.
Please think it twice to hire competent people.

Thanks.

@ohjames
ohjames commented Jan 16, 2015

@stryju Part of being a programmer now is being deluged in a sea of github repositories pretending that the software contained within works. Only after actually trying to use these projects, maybe even to the point where you start relying on them, do you realise half are garbage. After twenty or so such disappointments it's only natural then to remain calm in the face of yet another software project failure.

@Bumrang
Bumrang commented Jan 16, 2015

@xtraeme Mistakes happen, doesn't matter if you're competent or not.

@stryju
stryju commented Jan 16, 2015

@nuisanceofcats while this might be true, I'm still impressed how calm and polite @keyvin remained.
I went through a fair shareof github issues and this one caught my eye πŸ˜„

@xtraeme
xtraeme commented Jan 16, 2015

@Bumrang if you are executing rm -rf $VAR/* it's mandatory to check if the var is set! that's clearly incompetence.

@salum-ar

@Bumrang You got this open source thing all wrong. There is no room for civil or mature feedback. You should try emulate Linus like @xtraeme is doing and be abusive to anybody whose work displeases you. Because clearly people don't make mistakes, their work is an embodyment of who they are. You either are good developer or your not, there is no growth.

@ohjames
ohjames commented Jan 16, 2015

@stryju Yeah you're right he is pretty calm, I think we should worship him as the new Buddha. @keyvin Have you always been so cool and collected, can you share your secrets with us? If someone wiped my system I'd be like, nowhere near as cool as you.

@AgentME
AgentME commented Jan 16, 2015

While using set -u or similar could have prevented this mistake, it's lazy and considered bad style.

It may not a good idea to knowingly write code that relies on set -u, but it helps prevent accidents exactly like the one this thread is about. It doesn't break any sane code. Turning it on is opting into some much-needed sanity checks.

@stryju
stryju commented Jan 16, 2015

@nuisanceofcats exactly! 🍻

@MrSchism
Member

Seriously, though... lets try to keep things civil. There can be any of a bunch of reasons for this having slipped by. It's especially obvious with how Valve works (joining and leaving projects almost at whim). The code could have been put in place by someone who's not even at Valve any more and folks picking it up just went with it because it was working. It's something that you could easily miss if you're not looking for it and didn't experience an issue with it. Anyone using Steam for Linux and following best practices and inspecting scripts before running them could have found this bug ages ago (myself included; I'm not saying I'm not equally to blame).

Think about how long it took for this to get a ticket. Everybody missed it for over a year.

@rpdelaney

@skybert set -e and set -u are recognized as poor coding practice. From bash-hackers.org:

set -e causes untested non-zero exit statuses to be fatal. It is a debugging feature intended for use only during development and should not be used in production code, especially init scripts and other high-availability scripts. Do not be tempted to think of this as "error handling"; it's not, it's just a way to find the place you've forgotten to put error handling. Think of it as akin to "use strict" in Perl or "throws" in C++: tough love that makes you write better code. Many guides recommend avoiding it entirely because of the apparently-complex rules for when non-zero statuses cause the script to abort. Conversely, large software projects with experienced coders may recommend or even mandate its use. Because it provides no notification of the location of the error, it's more useful combined with set -x or the DEBUG trap and other Bash debug features, and both flags are normally better set on the command line rather than within the script itself. Most of this also applies to the ERR trap, though I've seen it used in a few places in shells that lack pipefail or PIPESTATUS. The ERR trap is not POSIX, while set -e is. failglob is another Bash feature that falls into this category (mainly useful for debugging). The set -e feature generates more questions and false bug reports on the Bash mailing list than all other features combined! Please do not rely upon set -e for logic in scripts. If you still refuse to take this advice, make sure you understand exactly how it works. See: Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected? and http://www.fvue.nl/wiki/Bash:_Error_handling

@markgraf

Correct me if I'm wrong, but AFAIK "$0" expands to the name the script has been invoked as, not the absolute path. (open a shell and try echo $0)
I guess this adds to the problem of not checking for unset variables...

$0 is useful for programs like busybox, that act differently depending on by what name they have been called.

Using it for filepath-magic OTOH opens yet another can of worms, as soon as there are symlinks involved: The regex can expand to a path that doesn't necessarily exist.

tl;dr: don't use $0 in paths.

@kasimon
kasimon commented Jan 16, 2015

@markgraf: $0 is the command the script was called with, for example emacs, or /usr/bin/emacs, or ../../bin/emacs. It's really just the first "word" of the command line. If you just want the name of the executable, use basename $0, if you want the full path, use readlink -f $0 (edit: except if $0 is a symlink, then readlink -f will return the full path to the symlink target).

@Stummi
Stummi commented Jan 16, 2015

actually $0 can be anything or nothing at all. See help exec in bash.

@keyvin
keyvin commented Jan 16, 2015

Everything is impermanent and transient. Especially bits on disk. No use crying over flipped bits.

I also don't want to get angry about it because steam for linux was a counter-thrust agaisnt microsoft turning windows into a walled garden with the app store. I didn't pay for steam for linux, and I appreciate that Valve is taking the time to make a proper port so we aren't all stuck running steam through wine.

If my root directory had to be sacrificed to appease the god of bugs, so be it. It'd be cool if I could get a special badge and an email apology from whoever added the #Scary! comment. That still makes me chuckle.

@terzag
terzag commented Jan 16, 2015

Came across a similar problem a few weeks ago when Steam started deleting files for unclear reasons; I killed the process as soon as I saw that. I first thought it was in its own dir, as I discovered that some games had been uninstalled but the maths didn't really add up. Now that I see this issue, I really wonder if I have lost important stuff (like backups of my work). I sure hope not but I'm pretty scared now.

Anyway, I haven't really understood from the long list of previous comments: is the issue fixed or not?

@jmallach

@markgraf, no not always, as it depends on invocation.
jordi@penyagolosa:~$ cat /tmp/meh
#!/bin/sh

echo "This is $0: $0"
echo "This is basename $0: $(basename $0)"

jordi@penyagolosa:~$ /tmp/meh
This is $0: /tmp/meh
This is basename $0: meh

@Noiwex
Noiwex commented Jan 16, 2015

This is platinum.

@In7rud3R

Priceless...

@Tydus
Tydus commented Jan 16, 2015

comment before it goes hot.

@korobochka

Wow.
I think it is time to move Steam to a separate user and/or chroot, just in case.

@dschissler

@Korobochka I think that its best to do that for all games. I also only run Skype from a Windows VirtualBox. Its hardly as secure as Qubes but I think that proprietary apps that do a lot of stuff should be isolated in at least some minor way.

@ghost
ghost commented Jan 16, 2015

This issue has been open for 2 days without any response, fix, or apology from Valve? What the actual f**k?

@sabueso
sabueso commented Jan 16, 2015

Fire in the hole

@aef
aef commented Jan 16, 2015

It's like Sierra Half-Life 1 installer all over again. The installer had a default target of C:\Sierra\Half-Life. If you changed this to C:\Games\Half-Life and later you uninstalled Half-Life 1, the uninstaller removed C:\Games completely. Great achievement for Valve to bring such behavior back.

Just a hint: Did you ever check the amazing quality and documentation of Valve's Linux dedicated servers? It is horrific, I spent so many hours debugging this stuff.

Oh by the way: Valve is an US company deploying an automatic software installer onto your free software operating system. Would also be a great place for NSA to access your system.

@ohjames
ohjames commented Jan 16, 2015

@stratumnine As far as we know this has only affected one person and that person is chill about it. There's no need to get aggressive on behalf of these hypothetical people who it also messed up. You should learn from @keyvin, chillest brother alive.

Remember kids, before you rage in github think: "What would @keyvin do."

Praise be to lord keyvin.

PS Valve should provide offerings to keyvin.

@carlosparamio

This might become even worst than bumblebee... it can potentially erase any network volume that you have mounted at your filesystem. Imagine if you have your NAS drive mounted...

@pythoneer

@nuisanceofcats no this happened to other people, too e.g. @onodera-punpun, @d00fy and other people reporting this on reddit r/linux

but nonetheless you are right about the tone especially these "w00t" ppl posting stupid pictures and posting nothing than bumblebee references which helped no one cuz there are so kewl.

@sebadoom

@nuisanceofcats It has not affected one person, read the second comment for instance. I myself might have been affected by this as well. I lost tons of files for no apparent reason a couple of days ago. I am still investigating what happened and just found out about this.

@killua99

I need to comment on this, because of yes. I use steam and omg!

Thanks for report this "scary bug"

@NoElyz
NoElyz commented Jan 16, 2015

Another genius.

@ju2wheels

Github is not a forum, if your comment is not related to the technical issue please stop posing and take it here: http://www.reddit.com/r/linux/comments/2sjjr3/warning_to_steam_users_dont_try_to_move_your/

@stuartpb stuartpb referenced this issue in progrium/bashstyle Jan 16, 2015
Open

Using defaults and "${VAR:?}" #29

@alexander-yakushev

but nonetheless you are right about the tone especially these "w00t" ppl posting stupid pictures and posting nothing than bumblebee references which helped no one cuz there are so kewl.

@pythoneer Yes, I'm kewl, what's your problem?

Bumblebee and this are not just bugs, they are gems. You can reference them in beginner's books where you say "don't do this, because that's what happens". I see nothing wrong with having some fun about it, especially if that causes people to remember it better.

@seanchannel

a change of language just gets you a change of bugs. this should be coded more responsibly and adhere to POSIX standards. we also need a real, hardened POSIX shell that is not just bash playing shadow puppets.

@Plaque-fcc

The reason most (source) distributions have a sandbox and a lot of
abstraction in their package manager is because they don't trust any
scripts/build-systems. Through the package manager it is usually not
possible to remove files that do not belong to the package, because
the files that belong to the package are recorded in a database.

Oh yeah, things like deb packages don't rely upon scripts and people
haven't had any trouble about them. Yes. And I didn't receive a gift
license key from a package maintainer for helping as a remote 3rd-party
to resolve such an issue happened to random user on IRC recently. Yeah.
Not possible to remove files or do crappy #Scary things with
system-wide privileges.

@ahamid
ahamid commented Jan 19, 2015

Does this affect Fedora, because I can't find a steam.sh on my system. I have a steam package from rpmfusion.

$ rpm -q steam
steam-1.0.0.47-2.fc20.i686

my /usr/bin/steam does not have any reference to reset or STEAMROOT or a wildcard "rm -rf" (it does have some rm -fs of specific files as well as an rm -fr $LAUNCHSTEAMPLATFORM/steam-runtime which seems a bit safer) . it contains the following line:

export STEAMSCRIPT_VERSION=100047
@Bengt
Bengt commented Jan 19, 2015

@ahamid I do have it under (slightly outdated) Fedora 20.

$ uname -r
3.17.8-200.fc20.x86_64
$  rpm -q steam
steam-1.0.0.49-3.fc20.i686
$ cat .local/share/Steam/steam.sh | grep Scary!
    # Scary!

My steam script seems to be a bit newer than yours:

$ cat /usr/bin/steam | grep STEAMSCRIPT_VERSION=
export STEAMSCRIPT_VERSION=100049

About Steam:

bildschirmfoto von 2015-01-19 03 35 13

I believe I have Steam from RPM fusion as well.

@ThePythonicCow

fcole90 commented 12 hours ago

This is still strange, the command "rm -rf /" cannot work from the steam
script because it needs super user privileges and also the additional
argument "no-preserve-root".

I beg to differ. That "rm -rf" command is recursive, silently forced, from the root '/' down.

Sure, whatever is directly in the root '/' directory is probably safe, because very few user systems are so badly configured that the root directory is user owned or user writeable (and those users have already decided to practice sky diving without a parachute.)

However, "rm -fr /" will traverse all mounted file systems, silently removing every file (no matter the file's permissions or ownership) in every directory, for any directory that allows user write permissions, and is below a directory path that is searchable (higher level directories are executable.)

Very few users have a backup strategy in place that will recover from that sort of damage without great pain and loss.

@ahamid
ahamid commented Jan 19, 2015

@Bengt Ow! You're right, I thought I checked everywhere for steam.sh but it is there under .local/share/Steam. Is there an interim safeguard - I feel like commenting this line out entirely. Actually the whole script is littered with rm -rf commands.

@Bengt
Bengt commented Jan 19, 2015

@ahamid See: #3671 (comment) ... In contrast, just left everything as it is for now, because it seems to me that fiddling around with Steam's files might cause more trouble. I am aware of the Steam's current volatile nature, make backups of my most valuable stuff and wait for an official fix.

@sosi-deadeye

It's better to rewrite the script in another language. Python should be a good language for this. It's not good to have unmaintable scripts like this. No one would read the code and no one want to do changes on the code, because it works anyway.

@vdrandom

@sosi-deadeye, and that would help exactly how? It is entirely possible to write bad and unreadable code in virtually every language out there.

@MrMEEE
MrMEEE commented Jan 19, 2015

@Valve: I know this stuff is opensource, but you don't have to copy all of my code :)

@fbt
fbt commented Jan 19, 2015

An even better fix, btw, would be to hardcode such things.
Guessing the script's location reliably is basically impossible for every case; it's a bad practice overall.

@sosi-deadeye

That would help to do it in the right way. Writing good readable shell
scripts is nearly impossible. Did you ever looked inside init-scripts? They
are doing lot of magic with including sources into the init scripts. But
the code ist unmaintainable. For example the srds_run is horrible to read.
I do understand the code, but never want to change anything there.

Jack Frost notifications@github.com schrieb am Mo., 19. Jan. 2015 12:25:

An even better fix, btw, would be to hardcode such things.
Guessing the script's location reliably is basically impossible for every
case; it's a bad practice overall.

β€”
Reply to this email directly or view it on GitHub
#3671 (comment)
.

@7eggert
7eggert commented Jan 19, 2015

Init scripts used to be small and maintainable. But if you add crude logic to also configure the application by collecting various information from around the system, you'll get a program containing tons of crude logic in any language.

Besides, system($PROG_RM." -rf ".$STEAMROOT."/*") would not be better.

@vdrandom

I don't get why '/*' is even needed. How better is it compared to { rm -R "$STEAMROOT"; mkdir "$STEAMROOT"; }? Using wildcards for removal, especially recursive, is a very, very dangerous thing to do to begin with, not to mention that -f is also barely ever needed.

@ryanpcmcquen

Redundant, but:

if [ "$STEAMROOT" != "" ] && [ "$STEAMROOT" != "/" ]; then
  rm -rf --preserve-root "$STEAMROOT/"*
fi

You could also add checks for typical linux directories:

/{usr,var,bin,sbin,etc}

You get the point here. Might not be a bad idea to force STEAMROOT to be inside of ~/ as well.

EDIT: Probably good to have both checks as not everyone is necessarily using GNU rm.

@hasufell

Oh yeah, things like deb packages don't rely upon scripts and people haven't had any trouble about them.

I don't think debian is a good example for QA.

The point was to move away from uninstall/cleanup methods that have undefined behavior and rather look up files from an internal database and _remove known files only_. That is a completely different concept.

This is just an example for: underestimated the problem to be solved. And Linux distros have decades of experience with this problem. Just use it. It's open source.

@Plaque-fcc

Oh yeah, things like deb packages don't rely upon scripts and
people haven't had any trouble about them.

I don't think debian is a good example for QA.
I just reminded you of the other side without which the system you
mentioned doesn't work. Likely, RPM too, as far as I can recall.

The point was to move away from uninstall/cleanup methods that have
undefined behavior and rather look up files from an internal database
and _remove known files only_. That is a completely different
concept.
Yes, I'd like this idea. If I don't remember trashed Win Registry and
all those Program Files folders with useless abandoned things the
initial installer database doesn't contain. This is not a panaceia,
sigh.

@hasufell

I just reminded you of the other side without which the system you mentioned doesn't work. Likely, RPM too, as far as I can recall.

You really miss the point. This is not about being bug-free, but about making fundamental mistakes less likely by introducing concepts that are more strict and allow less random effects (and that doesn't just involve a different language). That is pretty basic and I shouldn't have to explain it.

Repeating the whole history and all experiences of existent, widely tested solutions is valid, but not really smart. That's why we are here.

The current "fix" for this bug is still wrong.

Yes, I'd like this idea. If I don't remember trashed Win Registry and all those Program Files folders with useless abandoned things the initial installer database doesn't contain. This is not a panaceia, sigh.

You are just reminding us that windows is broken and mix it up with other arguments. That's not really a coherent argumentation.

@Plaque-fcc

The current "fix" for this bug is still wrong.
Here's where I agree.

@tzvetkoff

All bug fixes from Steam/Valve will be wrong unless they do a cultural change in how they write their software.

  • Talking about NTFS drives is something no one should even think about on Linux (the FS should never matter)
  • Not having case-sensitive drive support on MacOS X is even worse
  • And then here's this shit - rm -rf /*
  • Then again, how about Retina support? (and I'm not speaking of OS X only, I run a linux rig with a 4K display at work)
  • Please add anything you know of, I just got tired
@clopez
clopez commented Jan 20, 2015

@rpdelaney I don't agree with that. I think that using set -e and set -u is actually a very good coding practice. And the best example if this bug.

When one of the commands that your script runs returns an unexpected error, IMHO is always better to have the script aborting than to continue and risk causing some very undesirable situation (like wiping all your files).

For example, the Debian Policy Manual states that all maintaner scripts should either check every command for the return value or run with "set -e" defined (those are the scripts that are executed when a package is installed or removed: postinst/postrm/etc..):

Every script should use set -e or check the exit status of every command. 

https://www.debian.org/doc/debian-policy/ch-files.html#s-scripts

@panzi
Contributor
panzi commented Jan 20, 2015

@ryanpcmcquen Don't compare paths with =, use -ef:

if [ $EUID -eq 0 ]; then
    echo "This script should not be run as root!" 1>&2
    exit 1
fi

STEAMSH=$(readlink -e -- "$0")
STEAMROOT=$(dirname -- "$STEAMSH")

if [ ! -d "$STEAMROOT" -o "$STEAMROOT" -ef / -o "$STEAMROOT" -ef /home -o "$STEAMROOT" -ef "$HOME" ]; then
    echo "Illegal STEAMROOT: $STEAMROOT" 1>&2
    exit 1
fi

Warning: This code is untested.

@ryanpcmcquen

@panzi πŸ‘

What does -ef do?

@Xaekai
Xaekai commented Jan 20, 2015

@ryanpcmcquen

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

[ FILE1 -ef FILE2 ]
True if FILE1 and FILE2 refer to the same device and inode numbers.

@cebericus

I dont usually get critical in bug reports but seriously????? Just checking for null then deleting everything??

Check before removing

if [ "$STEAMROOT" != "" ]; then
rm -rf "$STEAMROOT/"*
fi

what if $STEAMROOT is a space char, ".." or a whole bunch of other possibilities. This still an untested amateur hour waiting to happen. There should be a list/db of items to delete and those should be the only possible items to ever delete with this script.

@AgentME
AgentME commented Jan 20, 2015

@cebericus $STEAMROOT is not going to have just any arbitrary value in it. An error in it being set leads to it being an empty string.

@cebericus

Sorry, but it does not matter. You cannot predict all future usages or changes to the script and depending on a discontinuous section of the code to insure that rm -fr behaves correctly is bad design and bad practice. Better safe than sorry.

@pilotforhire

@gdrewb-valve do you already have a plan for fixing that problematic maintenance script?

I am scared about further executing steam.sh after reading it as i saw many pitfalls in the code which can lead to undefined behaviour (or chaos).

I agree with @cebericus. Steam needs an installer/deinstaller application supported by a database where every installed file is registered, that would be a proper fix. "rm -r" is not an uninstallation routine.

@frnco
frnco commented Jan 21, 2015

Don't make a DB, please.

To anyone who suggests it: If you wanna be "this much safe" go back to Windoze. You have your db, and just gotta format every 6 months.

We just need better checks for rm -rf

@keyvin, amazing bug report by the way. A lot of people here could learned a few things from you. Hope you get to try something new after wiping your configuration, 10 year's is a long time and I surely would take the chance to try out a lot of new stuff.

On the matters of blaming: Don't "blame" developers for bugs, this will bite you in the ass sooner or later. EVERYBODY makes mistakes, at least a few of them. If you make only ONE and it wipes an entire system, you're still fucking amazing, and one person is allowed to hate you.

About changing the language: I completely disagree. I think we need better checks for where the executable is and where steam files are. I also think this shouldn't be a script in any language, this should be coded "properly", in whatever language, and not rely on anything, rather detecting all folders and files through brilliant coding. :D

If that's impossible, then the language doesn't matter, what matters is fixing every little bug and improving the errors. Introducing a bazillion python bugs to the "new script" is definitely the last thing we need.

Lastly, thanks to Valve for trying to make steam work in our insane Linux World (How many distros supported already? Runs flawlessly on Arch Linux, Manjaro, Bridge, Debian and Ubuntu, by the way) and all my loving to the developers who have to read stupid people talking as if their code in a GitHub comment would have fewer bugs than Valve's "because they are smarter that the entirety of Valve developers".

@7eggert
7eggert commented Jan 21, 2015

The only "database" needed is hardcoding ~/.local/share/Valve_Steam/ into the application, and maybe testing for /opt/Valve_Steam/. Linux does support symlinks, therefore hardcoding is no problem.

STEAMROOT=~/.local/share/Valve_Steam/
if [ \! -d "$STEAMROOT" ]; then
if [ -d /opt/Valve_Steam/ ]
then STEAMROOT=/opt/Valve_Steam/
else 
mkdir -p "$STEAMROOT"
if [ \! -d "$STEAMROOT" ]
then echo "cannot create $STEAMROOT"; exit 1
fi
fi
fi #untested

This may still go wrong, but it's by shooting your own foot, not by a script having unexpected behavior.

BTW: I suspect ~/.local/share is the wrong location, since "share" means "these data are the same across different CPU architectures, no need to have a different one on arm or sparc"
https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard

@vdrandom

@7eggert, it's XDG directory structure, see http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html. $XDG_DATA_HOME is used because there is no standard for storing arch-dependant binaries, libs and so on within $HOME.

@7eggert
7eggert commented Jan 21, 2015

Then XDG is to blame for being incomplete and bad.

@rpdelaney

@7eggert according to the Wikipedia citation you linked, /share is "Architecture-independent (shared) data." I can find no reference to ~/.local/share, nor to a standard meaning for share generally.

There is some basis for a precedent though, under /local: "Tertiary hierarchy for local data, specific to this host. Typically has further subdirectories, e.g., bin/, lib/, share/."

Along those lines, it would seem perfectly logical that if /local is "Tertiary hierarchy for local data specific to this host", then ~/.local/ would be "Tertiary hierarchy for local data specific to this user." And thus ~/.local/share is "Tertiary hierarchy for local data specific to this user that is architecture independent."

It's not clear how the XDG standard is "to blame for being incomplete and bad." It looks more like the XDG standard did not agree with your preconceptions about what share should mean when abstracted from any meaningful context.

@7eggert
7eggert commented Jan 21, 2015

You're describing my way of thinking. "share" == "shared data across systems".

My view about XDG is "It should work as intended even if I have $HOME mounted on my Mac and my PC, and you know why your 'solution' is intentionally and unnecessarily wrong."

@rpdelaney

I'm not persuaded, but on second look this seems really off topic for this bug report. Sorry for continuing the derail.

@panzi
Contributor
panzi commented Jan 21, 2015

@frnco Just as a side note: Using a DB is the Linux way. See all package managers. Some of them even transactionally install/remove packages. Also a typical Linux distribution has a release cycle of 6 months, meaning you have to reinstall your Linux system every 6 months (unless you think dist upgrade is not too risky for you). Sorry for being off topic.

@hasufell

@frnco

To anyone who suggests it: If you wanna be "this much safe" go back to Windoze. You have your db, and just gotta format every 6 months.

You probably don't know, but literally any linux distro package manager uses a DB.

@Tele42
Tele42 commented Jan 21, 2015

It seems what we want to do is confirm that the folder steam.sh wants to delete on a reset is the folder steam made in the first place, isn't this easy when you use an empty file as a marker? In pseudo-code, it would be: if test ( "$STEAMROOT/.steam.keep" file exists ) then delete folder contents, else tell user that this sanity check has failed and manual intervention is required (explicitly die here), end if. You add this .steam.keep file by either using the touch command or adding it to generic steam user download. Most users should not care you added a handful of filesystem bytes to prevent the bad scenario.

This should exclude all not target folders unless the user is willfully killing their own system.

@hasufell

@Tele42 this doesn't really tell you if you just wiped a lot of user files as well, but it's certainly better than just checking a variable for null

@Tele42
Tele42 commented Jan 21, 2015

@hasufell The upside is that it would seconds to minutes of dev time to implement.

@frnco
frnco commented Jan 21, 2015

@panzi I user Arch, so it's rolling release, I never reinstall. And I think no worries about off-topic on this case, it's pertinent. And you do have a good point, as @hasufell . I shouldn't be judgemental, using a DB is not a bad thing necessarily.

Still, I don't think it is a great way, especially in this case. I can see things easily going awry with a DB, especially considering Steam is, in a way, a Package Manager, and one with a bazillion games that each can do a lot of stuff on the system.

Steam would have to keep track of every file it had ever downloaded/created/edited/etc, and, considering the amount of games on Steam, I think that would take too long to code, raise complexity too much (And needlessly), take a LOT of disk space and a lot of time to run, plus it would increase the risk of bugs.

I think the best idea so far is testing the folder, checking if it is a valid path, if it's not a system directory, if it exists and if it has some specific files in it, and then deleting the tree. Adding a README.txt telling people not to copy files over there can also be great, but even Steam on Windows erases, for example, game mods if you tell it to check for corrupted files, so I don't think that's so bad. At least we're making sure Steam only "messes" its own directories.

Perhaps Steam should use some of the solutions from package managers. Perhaps that is the best way. I just think we need something more feasible for an immeadiate solution. And developing a system for tracking files plus a DB for those files because of one rm -rf deep in a bash script that went awry one time seems a bit overkill to me. Much more feasible to check before the rm -rf

@panzi
Contributor
panzi commented Jan 21, 2015

Yes, it cannot keep track of all the game files, because the games might create/change their files in an unknown manner to steam. But it could keep track of it's own files and of the game directories. Just recursively wipe the game directories without following symlinks, but exactly delete only known steam files. Anyway, I think better checks (like I wrote above) would be good enough.

@frnco
frnco commented Jan 21, 2015

@panzi I think "good enough" and "quickly" are the things we should be looking for in an answer to this bug. :D

@hasufell

Steam would have to keep track of every file it had ever downloaded/created/edited/etc, and, considering the amount of games on Steam, I think that would take too long to code, raise complexity too much (And needlessly), take a LOT of disk space and a lot of time to run, plus it would increase the risk of bugs.

First, there are already existent solutions for this and e.g. ChromeOS realized it can just use them. There is no reason to code something like this from scratch.

Second, I don't know what you mean with complexity exactly. Algorithmic complexity, LOC?

The argument of disk space is simply wrong. A DB can also be a simple text file and most package managers use plain text files.
You can test it yourself:

cd /steam/root/folder # make sure it worked, lol
find . -type f -exec echo '{}' >> mysteamdb.txt \;
du -sh mysteamdb.txt

The argument of runtime is just weird. I'd rather have it take 20 seconds more and be much more safe.

The argument of risk of bugs is even weirder. Shell scripts that are based on live filesystem checks and random variables are so full of side effects and undefined behavior (if you have dealt with autotools, then you know that shell definitely does have undefined behavior) that an abstraction layer is a very good solution to this problem. Sometimes a proper solutions takes more LOC. That's a fact.

@panzi
Contributor
panzi commented Jan 21, 2015

@hasufell If you want to be really exact use:

find . -type f -print0 >> mysteamdb.db

This will separate file names using nil bytes, because a newline is a valid character in file names under Linux. You can then do things like this:

xargs -0 < ~/mysteamdb.db ls -lh
@frnco
frnco commented Jan 21, 2015

@hasufell I was thinking about code complexity. More code, more functionality.

Your other points are indeed valid. 20 seconds is not horribly bad, and that's an engineering choice. I just think we should focus on the best bugfix, and allow engineers to develop the best solution they think they can, because we're not gonna design the ideal solution in here.

@7eggert
7eggert commented Jan 21, 2015

"undefined behavior" == "Don't do that then", not "find out what this version of that shell does in that corner case and use it"

@moorepants moorepants referenced this issue in sympy/sympy Jan 21, 2015
Merged

Add cross-platform support #8865

@FuturePilot

@frnco it wouldn't need to worry about game files. We're talking about the Steam client only. It would only have to keep track of the Steam client files.

@johnv-valve
Member

We shipped a one-line fix to avoid the one situation where we could reproduce the problem. We are still working on some more comprehensive changes, but we wanted to get a fix out there quickly in case this somehow hit anybody else.

If anybody knows how to actually reproduce this bug, please post the steps here or email me directly. So far we have not been able toe reproduce it and I would hate to be barking up the wrong tree if the problem is really somewhere else.

Also, I'd appreciate it if people would not use this bug report as a general discussion and debate forum. I don't want to lock the thread, but it is pretty hard to separate out the noise at this point. Thanks!

@Plaque-fcc

Am I only one who tries to understand why the hell Steam needs to wipe
a directory on my machine? Even if it was Steam who brought it here,
why should it ever wipe it? Can't it do something not dumb instead?

@frnco
frnco commented Jan 22, 2015

@Plaque-fcc Like leaving unused files forever keeping your bits flipped in unnecessary ways? Whatever. We're not here to discuss engineering decisions, we're here to comment on a BUG (By definition, something that didn't work as intended).

@johnv-valve I believe this one-liner deeply interests many people, plus we're all worried about unpredicted and/or unpredictable edge-cases. I'm not inclined to believe any one-liner can avoid all edge cases, so it would be great if said "one line" was provided for scrutiny, and if more checks for the variables used with rm and folders to be erased were put in place.

I also disagree with you (And I hope you get what I mean) in that it's not a matter of "can reproduce", it's a matter of "can happen", especially if later someone changes the script in any unpredictable way. Redundancy can feel horrible, but rm -rf is one of those cases I'm pretty sure it's FAR better to be safe than sorry, especially if you files are on the line.

@rpdelaney

@frnco

...it's not a matter of "can reproduce", it's a matter of "can happen"...

Establishing "can reproduce" is critical to preventing "can happen" since if you can't reproduce the error then you can't know if you've fixed it or not.

@Tele42
Tele42 commented Jan 22, 2015

@frnco the referenced one-liner is in the current steam linux beta client:

        # Check before removing
        if [ "$STEAMROOT" != "" ]; then
                rm -rf "$STEAMROOT/"*
        fi
@frnco
frnco commented Jan 22, 2015

@rpdelaney That's why I said "I hope you get what I mean".

Maybe it's even impossible to reproduce this issue on that file, especially after the one-liner, but if you look at just a block of code, it's easy to reproduce the "erasing of everything". We need at LEAST rm so let's test every line that includes rm.

rm -rf "$STEAMROOT/"*

This for instance is easy to debug and test. If you wanna, try writing unit tests for it (But please be careful of where you run it. :D).

Bugs that depend on state are easy to reproduce if you isolate the code and "guess" possible states. That's how we unit-test stuff isn't it? That's the kind of bugs that happen "only in production" or "only on your client's 6-year-old-pc with this and that specific software installed". Do you go to your clients to code on their computers whenever you find a bug...? Or do you just tell them you can't reproduce...?

Bash scripting, monolithic and confusing code... Complaining about needing to reproduce something under those coditions is not an argument, it is, at best, an excuse. The solution is easy: isolate the code, make it work properly whatever the "other lines" throw at it.

@Tele42 and @johnv-valve I would also worry about the risk of $STEAMROOT being /, *, ., .. etc (Symbols that have meanin on *NIX systems, basically) or a system folder (/opt, /home, /usr etc., obviously including User's home folder). Not that I would manually write checks for every possibility, I would first study on the matter to see which values could end up there, and how to best "sanitize" the variable, so to speak. i.e., if there's a flag to protect system folders, I would use it. If * only adds to the risk (Better Git Blame that to be sure it is not needed though, could be a fix for some other edge case), I would remove it. And so on.

The best fix seems to be checking the folder for some specific file(s), but that coupled with manual checks for $STEAMROOT and some flags to protect system files becomes pretty safe. It CAN go wrong, as everything on a computer (The nature of bugs), but at least the script "does its best" to avoid it, which I believe is what we all want: To feel the software we run tries to preserve us, our systems and our files.

@rpdelaney

@frnco

Do you go to your clients to code on their computers whenefer you find a bug...? Or do you just tell them you can't reproduce...?

I think that's what he's doing when he asks for help with reproducing the bug. I'm afraid I don't understand what you're getting at.

@frnco
frnco commented Jan 22, 2015

@rpdelaney I'm getting at "rm should be dealt with more care, especially if the script is too big and you can't unit-test it."

rm-rf /* is just a bit worse than rm -rf ./* or rm -rf ../* and so on.
It's a bit like protecting against race conditions: Never running on them is not enought reason to not try to protect against them. If there's a chance it could happen, as slim as it may be, you code in a way to prevent it. If you parse one file of 20b in one thread and another file of 200Mb on another thread, you don't just assume both files are finished after the 200Mb file finished, you check for both, even if it's a problem that won't surface under any normal circumstances.

Dealing with a bash script this big and confusing feels remarkably close to that. Feels like everything work, but an unchecked rm still erased a ton of files. Classic example where "better safe than sorry" could have prevented it with a handful of ifs. Ugly, perhaps, but safer. And since the script is already a mess, I don't see any reason not to add more and better checks, as many of the previous commenters.

@fbt
fbt commented Jan 22, 2015

Is it strictly necessary to do rm -rf "$STEAMROOT/"*?
Why not rm -rf "$STEAMROOT"; mkdir "$STEAMROOT"?

[[ -d "$STEAMROOT" ]] && {
    rm -rf "$STEAMROOT"
    mkdir "$STEAMROOT"
}

It will create a case where if "$STEAMROOT" is a symlink, we will remove it and put the new files in there. But:

  1. There is little reason to symlink the whole dir.
  2. The user should know what they did and what that implies.
  3. We drastically reduce the chances for something to go wrong.
  4. We could warn the user of the fact that $STEAMROOT is a symlink and let them deal with it.

And please consider hardcoding the path to "$HOME/.local/share/Steam":

if [[ "$XDG_DATA_HOME" ]]; then
    STEAMROOT="$XDG_DATA_HOME/Steam"
else
    STEAMROOT="$HOME/.local/share/Steam"
fi

Or just:

STEAMROOT="$HOME/.local/share/Steam"
@7eggert
7eggert commented Jan 22, 2015

@ftp: Having a symlink is necessary when %HOME is too small or if it would be insane to use the SSD for games.

@ryanpcmcquen

As I said before, this argument should be included: --preserve-root.

@hasufell

@7eggert

Having a symlink is necessary when %HOME is too small or if it would be insane to use the SSD for games.

No. Use mount -o bind.

@keyvin
keyvin commented Jan 22, 2015

@johnv-valve you should just lock this thread. Obviously people haven't
picked up on the whole "not a general discussion forum".

On Thu, Jan 22, 2015 at 11:12 AM, Julian Ospald notifications@github.com
wrote:

Having a symlink is necessary when %HOME is too small or if it would be
insane to use the SSD for games.

No. Use mount -o bind.

β€”
Reply to this email directly or view it on GitHub
#3671 (comment)
.

@7eggert
7eggert commented Jan 22, 2015

mount -o bind requires root privileges. The point of using $HOME is not to require root privileges, otherwise you'd use /var/lib/Steam.

Besides, it's system specific.

@vdrandom

@7eggert, you can also tell Steam where you want your games installed. It is entirely possible to set a custom SteamApps location in settings.

I'm sorry for contributing to the offtopic, it will be the last time I do this.

@clopez
clopez commented Jan 22, 2015

Q: How many developers take to fix a bug in a shell script?
A: 115 participants so far, still unfixed.

@MrSchism
Member
@rpdelaney

...is there anyone in the world who uses Steam on a linux machine where they can't escalate to root to make necessary configuration changes?

@MrSchism
Member

@mwestphal : @johnv-valve stated the following:

We shipped a one-line fix to avoid the one situation where we could reproduce the problem. We are still working on some more comprehensive changes, but we wanted to get a fix out there quickly in case this somehow hit anybody else.

If anybody knows how to actually reproduce this bug, please post the steps here or email me directly. So far we have not been able toe reproduce it and I would hate to be barking up the wrong tree if the problem is really somewhere else.

Also, I'd appreciate it if people would not use this bug report as a general discussion and debate forum. I don't want to lock the thread, but it is pretty hard to separate out the noise at this point. Thanks!

This potentially only a partial fix; discussion has been moved to the Steam forums. There the community can discuss and review the "one-line fix" and see if any suggestions can be offered.

@lamont-granquist lamont-granquist added a commit to chef/chef that referenced this issue Jan 26, 2015
@lamont-granquist lamont-granquist fix master
broken by merging #2431.  code was actually broken and the specs
were broken, not sure how it got into ready-to-merge in that state.

rolled back the FileUtils.rm_rf that was in the original patch since
it trashed my chef git repo and in light of:

ValveSoftware/steam-for-linux#3671

i think the rm_rf is a bad idea.
a151dea
@dsohler
dsohler commented Feb 10, 2015

Solution: Just don’t delete user data. Ever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment