Goal
[!NOTE]
This dive took 6.5 hours
The goal of this document is to dive deep into the following commands:
cd /
cd -
cd
cd ..
Target Audience
This document is intended for users who have a basic understanding of Linux command line operations and wish to deepen their knowledge of directory navigation commands, with simple copy-paste examples.
TOC
- Goal
- Target Audience
- TOC
- Backgrounds
-
Dive in
- How to check source code of
cdcommand? - How do we know which shell we are using?
- Let's quickly check the version
- Dive into the source code of
cd'sbin_cdcommand inzsh - Restricted shell check
- cd with chasing symbolic links
- Signal handling for control the signals during
cdexecution - zpushnode(dirstack, ztrdup(pwd));
-
Dive into
cd_get_dest() - Dive into cd_new_pwd()
- How to check source code of
- Others
Backgrounds
If you have had a chance to work with Linux, the commands above are pretty common for navigating through directories. You may already know what they do, but let's dive deep into each of them to understand their behaviors.
-
cd /:Navigates to the Root directory -
cd ..:Navigates to the Parent directory -
cd:Navigates to the Home directory (equivalent tocd ~) -
cd -:Navigates to the Previous directory
While the first three are straightforward, cd - behaves like a "Back" button. But how does the shell remember where I was?
Dive in
How to check source code of cd command?
type cd
# cd is a shell builtin
shell builtin means that the command cd is implemented directly within the shell (like bash, zsh, etc.)
How do we know which shell we are using?
echo $SHELL
# /bin/zsh
OR you may:
echo $0
# -zsh
Let's quickly check the version
/bin/zsh --version
# or: `zsh --version`
# zsh 5.9 (arm64-apple-darwin24.0)
Dive into the source code of cd's bin_cd command in zsh
[!INFO]
The following is a mirror link of the official repository ofzsh
https://github.com/zsh-users/zsh
The core functions are the following:
-
cd_get_dest(): does the initial argument processing -
cd_do_chdir(): actually changes directory, if possible -
cd_new_pwd(): does the ancillary processing associated with actually changing directory
Restricted shell check
if (isset(RESTRICTED)) {
zwarnnam(nam, "restricted");
return 1;
}
[!INFO]
zwarnnam is a compound word for:z(ZSH) +warn(WARNING) +nam(NAME)
A function for error output with consistent formatting.
This code checks if the shell is running in restricted mode by using the isset(RESTRICTED) function. If it is, it issues a warning message "restricted" using the zwarnnam function and returns 1, indicating an error. In restricted mode, certain commands, including changing directories - cd -, may be limited to enhance security.
Will return the following output when you try to use cd in restricted mode:
Prepare restricted shell:
zsh -r
# shell_session_history_enable:1: /usr/bin/touch: restricted
# shell_session_history_enable:2: HISTFILE: restricted
# cd ..
zsh: cd: restricted
cd with chasing symbolic links
chasinglinks = OPT_ISSET(ops,'P') || (isset(CHASELINKS) && !OPT_ISSET(ops,'L'));
chasinglinks is a boolean value, meaning is_chasing_symbolic_links or not.
It is true if :
- If user specifies
-Poption - If user has a preference setting CHASELINKS enabled
- You can temporarily override this setting by specifying
-Loption
- You can temporarily override this setting by specifying
Setup:
tmp_dir=$(date +%y%m%d_%H%M%S_test)
mkdir $tmp_dir && cd $tmp_dir
mkdir physical_path
ln -s physical_path symbolic_link
Check Setup:
ls -al
# total 0
# drwxr-xr-x 4 ajk staff 128 Nov 29 13:58 .
# drwxr-x---+ 73 ajk staff 2336 Nov 29 13:54 ..
# drwxr-xr-x 3 ajk staff 96 Nov 29 13:58 physical_path
# lrwxr-xr-x 1 ajk staff 13 Nov 29 13:58 symbolic_link -> physical_path
Test yourself:
cd symbolic_link
pwd
# /path/to/your/tmp_dir/symbolic_link
Test with -P option:
cd ..
cd -P symbolic_link
pwd
# /path/to/your/tmp_dir/physical_path
Test with CHASE_LINKS enabled:
cd ..
setopt CHASE_LINKS
cd symbolic_link
pwd
# /path/to/your/tmp_dir/physical_path
Override the CHASE_LINKS with -L option:
cd ..
cd -L symbolic_link
pwd
# /path/to/your/tmp_dir/symbolic_link
setopt
the command setopt is in Src/options.c
How to check the options set in your shell?
/* With no arguments or options, display options. */
if (!*args) {
scanhashtable(optiontab, 1, 0, OPT_ALIAS, optiontab->printnode, !isun);
return 0;
}
setopt
# chaselinks
# combiningchars
# interactive
# ...
How to check what options are not yet enabled in your shell?
unsetopt
# noaliases
# aliasfuncdef
# allexport
# ...
Signal handling for control the signals during cd execution
queue_signals();
Make sure that other signals (like interrupts) do not interfere with the execution of the cd command. This is important because changing directories is a critical operation, and we want to ensure it completes without interruption.
zpushnode(dirstack, ztrdup(pwd));
pwd contains the current working directory before changing it.
You can check dirstack by:
dirs -v
0 ~/Workspaces
1 ~/Workspaces/oss
Dive into cd_get_dest()
cd_get_dest returns the destination directory based on the arguments provided to the cd command. It handles various cases, such as:
- No arguments: returns the home directory
-
-: returns the previous directory from the directory stack - Specific path: returns the specified path
It returns NULL if there is an error, such as when the previous directory is not set.
Also it is shared by the following commands (Please note that they had to do this for performance/size optimization back in the days when memory and storage were more limited):
cdpushdpopd
if (!argv[0])
If argument is empty:
[!INFO]
popdstands for "pop directory" and is used to remove the top entry from the directory stack and change the current working directory to that entry.
if (func == BIN_POPD && !nextnode(firstnode(dirstack))) {
zwarnnam(nam, "directory stack empty");
return NULL;
}
You can manipulate this error log when your directory stack is empty:
# dirs -v
# 0 ~/Workspaces/directory
popd
# popd: directory stack empty
strcmp(argv[0], "-")
This part checks if the first argument to the cd command is a hyphen (-). If it is, the function retrieves the previous directory from the directory stack. If the stack is empty, it issues a warning and returns NULL.
Dive into cd_new_pwd()
Basically write the new working directory to the PWD environment variable and update the directory stack accordingly.

Top comments (0)