3 ms·
I've had to do something similar a long time ago in the mid-90s when Linux switched from libc5 to glibc6. In this case, I hadn't deleted everything, rather I'd
by acveilleux 11y ago
I've had to do something similar a long time ago in the mid-90s when Linux switched from libc5 to glibc6. In this case, I hadn't deleted everything, rather I'd stupidly upgraded libc locally.
After learning a valuable lesson in exactly how dynamic library work and the recommended process for live libc upgrade (don't do it if ABI changes) I fixed it by using my IRC client which was already running so unaffected to get a statically linked copy of /bin and /sbin from another machine, via DCC Send...
Recovery then consisted of restoring libc5 from slackware 3.2 install media.
I can't remember how I got root, either su was statically linked (believable since it's setuid) or I had a logged in root session. I did have to used the tcsh "echo *" trick for file listing and the shell built-in cd...
- teddyh 11y ago"cd" is always a shell built-in. It is not even possible to have a /bin/cd binary which does what "cd" does.
- GTP 11y agoWhy is impossible? Maybe I've understood why it is always built in: without it the shell wouldn't be able to navigate through the directory tree to find the executables of the commands. But once the shell has it, I think it would be rendundant (so nobody does it) but still possible to have a /bin/cd that navigates directories.
- duaneb 11y agoYou can't change the environment of the parent process, including CWD. `/bin/cd` would either be another process like all executables run by the shell, and not work, or special cased, at which point why make it an executable at all?
- schoen 11y agoThe parent comment's explanation is exactly right (although I might not use "CWD" in this context, because a reader might mistakenly think the working directory is determined by an environment variable). As an example, try python -c 'import os; os.chdir("/")' Notice that the working directory of your shell is unaffected. :-) Or: bash -c 'export foo=bar'; echo $foo
- Someone1234 11y agoThose examples are trying to change the directory on the shell's child process, not on the shell itself. That being said, aside from a kernel patch there is definitely no official way of doing it. This is the hacky way: http://stackoverflow.com/questions/2375003/how-do-i-set-the-working-directory-of-the-parent-process http://stackoverflow.com/questions/2375003/how-do-i-set-the-...
- schoen 11y agoI meant for my examples just to illustrate that a child process can't change the working directory or environment of the parent process.
- JoshTriplett 11y agoI can think of one way to write "cd" out-of-process from the shell: exec /bin/cd /some/path, which does chdir("/some/path") and execs your shell. You'd lose your history and similar state, but if you had a shell that didn't even put cd in-process, it probably doesn't have history either. Sample: /tmp$ exec /tmp/cd /bin /bin$ exec /tmp/cd /home /home$ exec /tmp/cd /usr /usr$ Sample code: #include <err.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { char *shell; if (argc != 2) errx(1, "Usage: exec cd /some/path"); if (chdir(argv[1]) == -1) err(1, "chdir"); shell = getenv("SHELL"); if (!shell || !*shell) shell = "/bin/sh"; execl(shell, shell, NULL); err(1, "exec"); }
- duaneb 11y agoHah, hadn't thought of that. Kind of CPS for processes. I'm not sure what that would gain you, though, as you'd have to either a) write both the cd and the user of the cd, and there are less awkward ways to do that than exec'ing, or b) you'd have to pass something ELSE to exec to return control after cd finishes. This seems a little awkward and I'm not sure what is being proven. :P
- aardvark179 11y agoIt's how very early version of Unix effectively did stuff, they exceed a program, and when it exited they exceed the shel again. When they introduced something like the fork/exec model we now have they discovered cd didn't work any more and had to write it as a built in. Now, for bonus points, work out how goto worked when it wasn't a built in.
- JoshTriplett 11y ago> It's how very early version of Unix effectively did stuff, they exceed a program, and when it exited they exceed the shel again. Makes sense, since those systems might not have enough memory to run the shell and another program at the same time.
- 11y ago
- rleigh 11y agoIt's impossible because it simply calls chdir(2). The "current directory" is a property of a process; having it built-in means it changes the directory of the current process. If it was a separate executable, you'd change the directory in a separate child process for that executable, and the current directory of the shell would be unchanged, making it entirely useless.
- acveilleux 11y agoGood point. I'd never really thought about that, just noticed that all shells seemed to include id...
- bitwize 11y agoThat's why I freakin' love Slackware. The ability to repair stuff by hand, or even to get libc6 binaries running on a libc5 system (by putting the appropriate .sos in /lib), was a godsend during my early Linuxing, and completely unthinkable under Windows. It's very nearly unthinkable under Ubuntu or Fedora, but Slackware just keeps chugging the best it can no matter what shape you bash it into.
- Joeri 11y agoTo be fair to windows, its backwards compat is legendary. I'm still using windows software on windows 8 that was last compiled in 1997.
- acveilleux 11y agoAt one point I used a production proprietary DB engine last compiled in that time frame on Linux. The hoops needed to run it on semi-modern Linux was a real PITA (think chroot jail and some ld shenanigans to patch shared libs). Microsoft's backward compatibility is reallly hard to do.