Live data from Hacker News

How does `cd` work?

blog.safia.rocks

31–40 of 93 posts

Re: How does `cd` work?

#31
post #21

Not to be negative, but for learning: There are a few "problems" with this snippet of the article: ---- $ which cd /usr/bin/cd $ cat /usr/bin/cd #!/bin/sh # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $ # This file is in the public domain. builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"} Oh, bother! Reading shell scripts can be such a hassle sometimes. I know the tr comma…

> If /usr/bin is on a case-insensitive filesystem, and you execvp("CD", ...)

That seems like fairly rare edge case, considering that UNIX typically had case-sensitive file-systems, or rather handled filenames as opaque blobs. I wonder what actual system caused the need for case folding? Maybe HFS?

Re: How does `cd` work?

#32

Earlier quoted context omitted.

This looks fiendishly clever, if it really works, but I don't have time to dig through the 'ptrace' man page to figure out what it's doing. Can someone summarize?

Let me give it a shot: ptrace(2) allows processes to control other processes for debugging (for example, GDB and LLDB use it). What it's doing is gaining privileges to debug your shell process, using this privilege to gain control over its memory, and then just copying over the directory string to the right spot so that the shell thinks it has a new working directory.

Actually looks like it copies the path into the address space of the parent, backs up some register state, tickles the i386 syscall interface by setting registers to call chdir(2), then restores the registers to their original state, resuming the program already in progress.

Re: How does `cd` work?

#34

Random piece of info about cd: cd.. (no space between "cd" and "..") works on Windows

Or try zsh with a good pre-made config like grmlzshrc[1]. It allows changing to a directory by typing only its name (or path). This includes the .. directory. Doesn't get faster. [1] https://grml.org/zsh/

bash: `shopt -s autocd`

Re: How does `cd` work?

#35
> I decided to dive into the code for the Bourne shell to see what I might be able to figure out about these builtins. I came across the definition of the cd builtin here. (link to: http://git.savannah.gnu.org/cgit/bash.git/tree/builtins/cd.d...)

no, you came across the definition of bash's 'cd' builtin there..

On FreeBSD with a source checkout, the definition of /bin/sh's (the 'ash' shell, https://en.wikipedia.org/wiki/Almquist_shell) cd builtin is in:

/usr/src/bin/sh/cd.{c,h}

or, on the web:

https://svnweb.freebsd.org/base/head/bin/sh/cd.c?revision=32...

similarly, most anything in base is available in:

/usr/src/{path with '.' instead of slash}/{command name}

which is by the way, very handy, and in combination with having all your self built packages in /usr/ports/distfiles/.tar. a big plus of running a BSD system from source..

Re: How does `cd` work?

#36
post #8

I tried to create a command line tool that mimics some behavior of a bookmark manager in the terminal. https://github.com/serv/lbm Unfortunately, I learned that there's is no way to invoke cd programmatically from a program, but I didn't get an explanation I could understand why this is not possible. Can someone explain why you can't invoke cd from a program?

Letting a program arbitrarily modify another program's working directory or its environment variables would be a nightmare for any program that accesses files from relative paths, I think it's pretty obvious why you wouldn't be allowed to do something like that.

Re: How does `cd` work?

#37
post #8

I tried to create a command line tool that mimics some behavior of a bookmark manager in the terminal. https://github.com/serv/lbm Unfortunately, I learned that there's is no way to invoke cd programmatically from a program, but I didn't get an explanation I could understand why this is not possible. Can someone explain why you can't invoke cd from a program?

I have had this snippet in my `.bashrc` for years. No idea who to give credit to:

    #    eg. save mc
    #    cd mc # no '$' is necessary

    if [ ! -f ~/.dirs ]; then  # if doesn't exist, create it
        touch ~/.dirs
    fi

    alias show='cat ~/.dirs'
    save (){
        command sed "/!$/d" ~/.dirs > ~/.dirs1; \mv ~/.dirs1 ~/.dirs; echo "$@"=\"`pwd`\" >> ~/.dirs; source ~/.dirs ;
        source ~/.dirs  # Initialization for the above 'save' facility: source the .sdirs file
    }
    source ~/.dirs  # Initialization for the above 'save' facility: source the .sdirs file
    shopt -s cdable_vars # set the bash option so that no '$' is required when using the above facility
What this does is, whenever you're in a directory that you'd like to "bookmark" as you'd call it. Just type `save whatevername`. Then, when you navigate somewhere else you can type `cd whatevername` and it'll change you back there. It's simply adding to this ~/.dirs file and so overwriting is taken care of by just saving the same name in a new (or the same) directory. It just appends a line.

Also, you can just type `show` and any point and it'll tell you what you've saved and where.

The nicest thing is that this persists with new logins (the only drawback is that other shells that are running don't get the update automatically).

Re: How does `cd` work?

#38
I long ago wrote a cd replacement for Windows. It does a few clever things I like, but I always felt slightly unclean for how it works. Since it's external to cmd, it has to find the cmd parent-process that launched it, write a thread into the process space, then launch that thread that does the call to SetCurrentDirectory and updates the necessary environment variables.

It works, but I'm not entirely sure it should work.

Re: How does `cd` work?

#39
On the one hand, I admire the search for knowledge, taking things apart and seeing how they work. On the other hand, this seems a bit cargo-cultish. It's as if I took apart a record player, trying to see how it plays music, and I told you it works because the motor turns the the record.

In this case, the author got tangled in the shell script and code, and totally missed the whole subtlety and complexity of the Unix architecture. I expected to see something about the processes, file system, and directory entries. Even after the author added key information that was emailed to him by a reader, he didn't really follow up or try to understand more. I understand that not all coders have or need a degree in computer science, but it really surprises me what this author doesn't know (and doesn't know he doesn't know).

Another example from his next blog about 'ls': "I’ll admit, scrolling through all this C-code can be a little tiresome. Oh, how I miss the days when all I had to do was read JavaScript source! Because C gives you so little out of the box, a lot of the code that you end up reading is not that interesting. It’s largely the kind of stuff that higher level languages implement in their standard library." [https://blog.safia.rocks/post/171381157060/looking-into-ls]

Here's a book about Unix, among many (I got this one as a CS graduation present): https://www.amazon.com/Magic-Garden-Explained-Internals-Rele...

Re: How does `cd` work?

#40
post #21

Not to be negative, but for learning: There are a few "problems" with this snippet of the article: ---- $ which cd /usr/bin/cd $ cat /usr/bin/cd #!/bin/sh # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $ # This file is in the public domain. builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"} Oh, bother! Reading shell scripts can be such a hassle sometimes. I know the tr comma…

https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/a...

One of the most famous shell-portability issues is related to "$@". When there are no positional arguments, Posix says that "$@" is supposed to be equivalent to nothing, but the original Unix version 7 Bourne shell treated it as equivalent to "" instead, and this behavior survives in later implementations like Digital Unix 5.0.

The traditional way to work around this portability problem is to use ${1+"$@"}.

Post reply on HN