Shell Commands
Some Basics
空格 space 在 shell commands 中用于 sparate arguments,例如foo=bar, echo $foo, 但不可以foo = bar, 因为这样会被看做 call program foo with first argument '=' and second argument 'bar'.
echo Hello # 字符串输出
echo "Hello World" # 字符串用双引号包裹
echo Hello\ World # 使用了 \ 来escape
echo $PATH # 从这些 path 中搜索 commands
which echo # 查看是哪个 echo 被使用
pwd # print working directory
cd .. # change directory (to parent directory)
cd - # cd 到上一个路径(switch)
ls -al .. # list (all and long formatted) contents of parent dir
mv hello.py foo.py # move or rename
cp hello.py foo.py # copy
rm foo.md # remove
man ls # manual pages for ls
touch 1.py # create new empty file
touch -t YYYYMMDDHHMM.SS filename # 改时间
# 重定向
echo hello > hello.txt # > < 用于重定向
cat hello.txt
cat < hello.txt > hello2.txt # 1 cat hello.txt 2 cat 的输出
cat < hello.txt >> hello2.txt # >> 表示append,hello2.txt里会有两行hello
# piple
# left | right,左边的output是右边的input(不一定非是文本,image video也可以)
ls -l / | tail -n1 # 只显示1行
curl --head --silent baidu.com | grep -i content-length | cut --delimiter=' ' -f2
# 输出81 (Content-Length: 81)
echo 1060 | sudo tee brightness # tee 写入文件并在terminal显示
也可以写一个“自己的command”
touch mcd.sh
# vim mcd.sh
mcd () {
mkdir -p "$1"
cd "$1"
}
# :wq
source mcd.sh # 可以加入到.bashrc
mcd test # shell里面就可以用mcd了
$ (dollar sign)
参考stackoverflow,
$0表示script name;$1 ~ $9 positional argument,如果多于10,那么 ${10};$@ 所有的positional arguments;$*也是所有的参数,但不太一样 $@ 和$*的区别,结论是被双引号引起来的时候,$*会将所有的参数作为一个整体, $@会将各个参数分开,也就是更适合用于for;$#是参数的数量;$? is the most recent foreground pipeline exit status;$! is the PID of the most recent background command。
quoting
echo "hello world"
echo hello\ world # \移除后面一个字符的特殊含义
echo "#!/bin/sh" # echo表现不正常
echo '#!/bin/sh' # 单引号可以阻止所有interpretation,而双引号只能解决大部分
# 但也不是说应该处处使用单引号,比如
foo=bar
echo "hello $foo" # output: hello bar
echo 'hello $foo' # output: hello $foo
& | || [ > 2> >> <()
./server.sh & # run in the background
ls | grep .sh # pipe, 上一条输出喂给下一条
mkdir test && cd test # and, first is true then second
cd test || mkdir test # or, first is false then second
mkdir test1; mkdir test2 # do both whether first one is valid or not
cat < hello.txt > hello2.txt # 1 cat hello.txt 2 cat 的输出
cat < hello.txt >> hello2.txt # >> 表示append,hello2.txt里会有两行hello
cat <(ls) <(ls ..) # 两个地方的ls显示,<()把ls放在temporal file里
globbing
# {} cartesian product
touch foo{,1,2} # zsh下tab变成 touch foo foo1 foo2
echo {a..e} # a b c d e
touch dir{1,2}/foo{1..4}
ls -l 解读
-rwxr-xr-x 1 xushenglee staff 48B Jan 28 20:22 2.sh
-rwxr-xr-x 1 xushenglee staff 76B Apr 25 17:21 3.sh
drwxr-xr-x 2 xushenglee staff 64B Jan 25 18:48 My Docs
第一列10个字符,第一个字符 ( d 或 - ) 表示是dir还是file,其他的还有比如 l 表示symbolic link,剩下9个字符3个一组,表示permission。owner (read write execute), group (read write excute), everyone else (read, write execute)。
对于 file read write execute 就是字面上的意思,但对于 directory,read 表示是否可以看见dir里有什么,相当于 ls;write 表示 rename dir,create or remove file in it(有个坑的地方,如果有 file 的 w,但没有其 dir 的 w,那么可以清空 file,但是不能删除该文件,因为没有对 dir 的写权限);execute 表示是否可以进入(cd)该文件夹。
Different Shells
Shortcuts
crtl + l # 相当于 clear
# !! 补全上一条命令
rm -rf somedir # permission denied
sudo !! # 回车或者空格
sudo rm -rf somedir # 帮你补全好了
# !$ 补全上一条命令的最后一个参数
ls dir1 dir2
ls !$ # => ls dir2
# 补全上一条命令的第一个参数
ls -al !^ => ls -al dir1
# 补全上一条命令的所有参数
ls !* => ls dir1 dir2
# {} cartesian product
touch foo{,1,2} # zsh下tab变成 touch foo foo1 foo2
sed command
cat Downloads/abc.txt | sed -nE 's/.*([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}).*/\1/p' | sort | sed -e 1b -e '$!d'