Shell Tools and Scripting · the missing semester of your cs education

Shell Tools and Scripting · the missing semester of your cs education
  • Metadata:
  • 总结
    • [[01. Linux 和 命令行]]

To assign variables in bash, use the syntax foo=bar and access the value of the variable with $foo. Note that foo = bar will not work since it is interpreted as calling the foo program with arguments = and bar. In general, in shell scripts the space character will perform argument splitting. This behavior can be confusing to use at first, so always check for that.

To assign a variable, use = without space
To use a variable, simply add $ before it

Strings in bash can be defined with ' and " delimiters, but they are not equivalent. Strings delimited with ' are literal strings and will not substitute variable values whereas " delimited strings will.

备注: ' no variable

Here $1 is the first argument to the script/function. Unlike other scripting languages, bash uses a variety of special variables to refer to arguments, error codes, and other relevant variables. Below is a list of some of them. A more comprehensive list can be found here.

  • $0 - Name of the script
  • $1 to $9 - Arguments to the script. $1 is the first argument and so on.
  • $@ - All the arguments
  • $# - Number of arguments
  • $? - Return code of the previous command
  • $$ - Process identification number (PID) for the current script
  • !! - Entire last command, including arguments. A common pattern is to execute a command only for it to fail due to missing permissions; you can quickly re-execute the command with sudo by doing sudo !!
  • $_ - Last argument from the last command. If you are in an interactive shell, you can also quickly get this value by typing Esc followed by . or Alt+.

备注: 脚本名
单个参数 | 所有参数 | 参数个数
!! 上个命令(对忘 sudo 十分有用)

Commands will often return output using STDOUT, errors through STDERR, and a Return Code to report errors in a more script-friendly manner.


Exit codes can be used to conditionally execute commands using && (and operator) and || (or operator), both of which are short-circuiting operators. Commands can also be separated within the same line using a semicolon ;. The true program will always have a 0 return code and the false command will always have a 1 return code. Let’s see some examples


false || echo "Oops, fail"
# Oops, fail

true || echo "Will not be printed"

true && echo "Things went well"
# Things went well

false && echo "Will not be printed"

true ; echo "This will always run"
# This will always run

false ; echo "This will always run"
# This will always run

对于 OR || ,在 Condition_1 为 False 才会执行 Conidition_2
对于 AND && 在 Condition_1 为 True 才会执行 Conditon_2

Another common pattern is wanting to get the output of a command as a variable. This can be done with command substitution. Whenever you place $( CMD ) it will execute CMD, get the output of the command and substitute it in place. For example, if you do for file in $(ls), the shell will first call ls and then iterate over those values.

备注: $(CMD) 执行

A lesser known similar feature is process substitution, <( CMD ) will execute CMD and place the output in a temporary file and substitute the <() with that file’s name. This is useful when commands expect values to be passed by file instead of by STDIN. For example, diff <(ls foo) <(ls bar) will show differences between files in dirs foo and bar.

备注: <() 将 STDOUT 存到临时文件,Pass by file!

information dump

Good words for Collage Education in China xDDD

When performing comparisons in bash, try to use double brackets [[ ]] in favor of simple brackets [ ]. Chances of making mistakes are lower although it won’t be portable to sh. A more detailed explanation can be found here.

备注: TLDR use [[ ]]

Writing bash scripts can be tricky and unintuitive. There are tools like shellcheck that will help you find errors in your sh/bash scripts.

备注: 其实不太好用,规矩很多,小脚本其实没那么多规矩

Functions are executed in the current shell environment whereas scripts execute in their own process. Thus, functions can modify environment variables, e.g. change your current directory, whereas scripts can’t. Scripts will be passed by value environment variables that have been exported using export

备注: Function can change var, scripts cant
Not that clear See also

As with any programming language, functions are a powerful construct to achieve modularity, code reuse, and clarity of shell code. Often shell scripts will include their own function definitions.


Beyond listing files, find can also perform actions over files that match your query. This property can be incredibly helpful to simplify what could be fairly monotonous tasks.

# Delete all files with .tmp extension
find . -name '*.tmp' -exec rm {} \;
# Find all PNG files and convert them to JPG
find . -name '*.png' -exec convert {} {}.jpg \;


To bridge this disconnect there’s the xargs command which will execute a command using STDIN as arguments. For example ls | xargs rm will delete the files in the current directory.

备注: 把 STDIN 作为 Pipe 的参数


建立国内可访问的 Blogger

Command-line Environment · the missing semester of your cs education

gdb 简明使用教程