Linux中的特殊符号以及特殊语法
辨别||、&&、;、$*等符号在linux中的含义与或# 将&&前后的两个命令当做一个表达式,如果表达式出错,那么可以认为该表达式为false➜ ~ ls / && datebin boot dev etc home initrd.img
辨别||、&&、;、$*等符号在linux中的含义
与或
# 将&&前后的两个命令当做一个表达式,如果表达式出错,那么可以认为该表达式为false
➜ ~ ls / && date
bin boot dev etc home initrd.img initrd.img.old lastore lib lib64 lost+found media mnt opt proc root run sbin snap srv sys tmp usr var vmlinuz vmlinuz.old
Thu Mar 21 14:18:44 HKT 2019
# 第一个命令失败,后面的命令不再执行。短路,因为表达式整体的值已经可以通过第一个表达式获得。
➜ ~ ls /hello && date
ls: cannot access '/hello': No such file or directory
# 与&&恰好相反
➜ ~ ls /hello || date
ls: cannot access '/hello': No such file or directory
Thu Mar 21 14:19:03 HKT 2019
# 第一个执行成功,已经可以获得整个表达式的值,所以不执行第二个表达式。短路。
➜ ~ ls / || date
bin boot dev etc home initrd.img initrd.img.old lastore lib lib64 lost+found media mnt opt proc root run sbin snap srv sys tmp usr var vmlinuz vmlinuz.old
分号;
表示过程,不计算值,因此按顺序执行。
➜ ~ ls / ; date
bin boot dev etc home initrd.img initrd.img.old lastore lib lib64 lost+found media mnt opt proc root run sbin snap srv sys tmp usr var vmlinuz vmlinuz.old
Thu Mar 21 14:23:48 HKT 2019
➜ ~ ls /hello ; date
ls: cannot access '/hello': No such file or directory
Thu Mar 21 14:23:52 HKT 2019
$相关表达式
$0, $1, $2, $3, $4, $5, $6, $7, $8, $9, ${10}, ${11}.....指令本身为0。后面为传入参数。个位数的,可直接使用数字,但两位数以上,则必须使用 {} 符号来括住。
#!/bin/bash
echo $#
echo $*
echo $@
echo $0
echo $1
echo $2
echo "--------"
# 当 $* 和 $@ 不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。
for a in $*
do
echo ${a}
done
for a in $@
do
echo ${a}
done
echo "--------"
# 但是当它们被双引号" "包含时,就会有区别了:
# "$*"会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。
# "$@"仍然将每个参数都看作一份数据,彼此之间是独立的。
for a in "$*"
do
echo ${a} # 这 2 个参数会合并到一起形成一份数据,它们之间是无法分割的
done
for a in "$@"
do
echo ${a} # 这 2 个参数是相互独立的,它们是 2 份数据
done
输出如下:
➜ Documents ./shell.sh hello world
2
hello world
hello world
./shell.sh
hello
world
--------
hello
world
hello
world
--------
hello world
hello
world
$? 获取上一个命令的退出状态
➜ ~ pkill -f xxxxoooo
➜ ~ echo $?
1
$!和$$
# Shell最后运行的后台Process的PID
➜ ~ ping www.baidu.com > /dev/null &
[1] 14025
➜ ~ echo $!
14025
# Shell本身的PID(ProcessID)
➜ ~ ps -ef | grep -v grep | grep zsh
sasurai 9143 9122 0 09:48 pts/1 00:00:00 /usr/bin/zsh
sasurai 11946 5190 0 14:32 pts/4 00:00:00 /usr/bin/zsh
sasurai 19350 19085 0 10:52 pts/0 00:00:00 /usr/bin/zsh -i
➜ ~ echo $$
9143
输出/输入重导向
| 文件描述符 | 名称 | 常用缩写 | 默认值 |
|---|---|---|---|
| 0 | 标准输入 | stdin | 键盘 |
| 1 | 标准输出 | stdout | 屏幕 |
| 2 | 标准错误输出 | stderr | 屏幕 |
我们在简单地用<或>时,相当于使用 0< 或 1>(下面会详细介绍)。
cmd > file把cmd命令的输出重定向到文件file中。如果file已经存在,则清空原有文件,使用bash的noclobber选项可以防止复盖原有文件。cmd >> file把cmd命令的输出重定向到文件file中,如果file已经存在,则把信息加在原有文件後面。cmd < file使cmd命令从file读入
cmd << text从命令行读取输入,直到一个与text相同的行结束。除非使用引号把输入括起来,此模式将对输入内容进行shell变量替换。如果使用<<- ,则会忽略接下来输入行首的tab,结束行也可以是一堆tab再加上一个与text相同的内容,可以参考後面的例子。cmd <<< word把word(而不是文件word)和後面的换行作为输入提供给cmd。cmd <> file以读写模式把文件file重定向到输入,文件file不会被破坏。仅当应用程序利用了这一特性时,它才是有意义的。cmd >| file功能同>,但即便在设置了noclobber时也会复盖file文件,注意用的是|而非一些书中说的!,目前仅在csh中仍沿用>!实现这一功能。: > filename把文件"filename"截断为0长度.# 如果文件不存在, 那么就创建一个0长度的文件(与'touch'的效果相同).
cmd >&n把输出送到文件描述符ncmd m>&n把输出 到文件符m的信息重定向到文件描述符ncmd >&-关闭标准输出cmd <&n输入来自文件描述符ncmd m<&nm来自文件描述各个ncmd <&-关闭标准输入cmd <&n-移动输入文件描述符n而非复制它。(需要解释)cmd >&n-移动输出文件描述符 n而非复制它。(需要解释) 注意: >&实际上复制了文件描述符,这使得cmd > file 2>&1与cmd 2>&1 >file的效果不一样。
for循环
for var in 集合
do
cmd1...
done
while循环
while [ 条件 ]
do
echo "hello"
done
if条件语句
if [ 条件 ]; then
cmd1
elif [ 条件 ]; then
cmd2
else
cmd3
fi
case语句
case 值 in
模式1)
command1
command2
command3
;;
模式2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac