Last Updated: 2023-06-01 09:23:38 Thursday
-- TOC --
在Bash命令行中,常常见到各种奇奇怪怪的符号,比如分号[;],&&,|,||,>,<,>>,<<,<<<,冒号[:],&,~和~+,|&
,有些头大,本文尽量总结。
这些符号及其功能是Bash提供的,命令程序并不知道这些符号的存在;因此,给命令行的输入,在Bash中执行与不在Bash中执行,有些是不一样的。
;
]分号的作用,就是简单的将多个命令分开,并列开来,就像C语言或Python中的多条语句写在了同一行,需要用分号来隔开。
$ echo 1; echo 2; echo 3
1
2
3
$ clear; ls
...
但我发现,有的时候也会执行失败,也许这种用法有些怪异吧:
$ alias kk='echo cs.pynote.net'; kk; unalias kk;
kk: command not found
分号[;]是命令的结束符,使得一行可以放置多个命令,上一个命令执行结束后,再执行第二个命令。使用分号时,第二个命令总是接着第一个命令执行,不管第一个命令执行成功或失败。
分号在Bash脚本中也有作用,它同样表示一个命令的结束:
$ if true; then echo cs.pynote.net; fi
cs.pynote.net
$ if false; then echo cs.pynote.net; fi
两个特殊的极其简单的命令:
$ true
$ echo $?
0
$ false
$ echo $?
1
与一般编程语言中的TRUE和FALSE的值完全相反!
&&
&&
这个符号在C语言中,就是and的意思,用来连接2个或多个条件判断,从左到右判断,直到遇到第一个不为True的条件停止,因为这时整个条件判断的结果已经确定,后面如果再有其它条件,也不需要判断了。
把这个思路用在Bash的命令行,也是一样的,Bash本就是可编程的Shell。如果前面的命令执行成功,则继续执行后面的命令,否则后面的命令就不用执行了。
command1 && commmand2 && ...
常见的用法有:
$ make && make install
如果make成功,则继续make install。
||
||
就是 or 的意思,跟 &&
一样,在命令行中,成了命令组合的条件判断语句。如果前面的命令执行成功,后面就不用执行了,整个条件判断已经确定为True。只有在前面的命令执行失败的情况下,才会执行后面的命令。
command1 or command2 or ...
例如:
$ echo 123 || echo 456
123
echo 123
执行成功,就不会再执行 echo 456
了。
$ mkdir repos || mkdir foo
mkdir: cannot create directory ‘repos’: File exists
$ ls
foo repos
因为repos目录已经存在,因此 mkdir repos
会失败,此时执行 mkdir foo
,用 ls
命令,可以看到foo目录创建成功。
&&
和||
混用$ cmd1 && cmd2 || cmd3
这里只跟true or false有关,不管true是0还是1!
$ true && echo '1' || echo '2'
1
$ true && false || echo '2'
2
$ false && echo '1' || echo '2'
2
$ cmd1 || cmd2 && cmd3
$ false || echo '1' && echo '2'
1
2
$ false || false && echo '2'
$ true || echo '1' && echo '2'
2
更多测试代码,有些还带括号:
$ true && echo '1' || echo '2'
1
$ false && echo '1' || echo '2'
2
$ false && (echo '1' || echo '2') # no output
$ false && echo '1' || echo '2'
2
$ (true && false) && echo '1' # no output
$ (true && false) || echo '1'
1
$ true || (echo '1' && echo '2') # no output
$ true || echo '1' && echo '2'
2
$ (true || echo '1') && echo '2'
2
在看一个:
$ a=1
$ b=2
$ [ a == b ] || echo '1' && echo '2'
1
2
$ ([ a == b ] || echo '1') && echo '2'
1
2
网上有人称
;
,&&
,||
为命令组合符号
。
>
|<
这是linux命令行中的重定向符号,作用是将左边命令的输出,重定向到某个位置,可以写入文件,或者将stdout重定向到stderr。
每个 Unix/Linux 程序(命令)运行时都会默认打开三个文件描述符(file descriptor,FD):
标准输入文件(stdin):stdin的文件描述符为0,程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,程序会向stderr流中写入错误信息。(stderr没有缓存,写入stderr的数据会立即输出!)
$ echo 'cs.pynote.net' > a.txt
$ cat a.txt
cs.pynote.net
使用
>
重定向到文件,如果文件不存在则创建,如果文件存在,先清空再写入。这个符号很容易一不小心就将文件内容清空,小心!
$ command > file
# 将 stdout 重定向到 file,注意不包括重定向stderr。
$ command < file
# 将file的内容作为命令的标准输入。
$ command 2>file
# 将stderr的内容重定向到file,注意不包括重定向stdout。
$ command > file 2>&1
# 将stdout重定向到file,同时将stderr重定向到stdout,
# 这样设置的效果就是,stdout和stderr都重定向到了file。
$ command 2>/dev/null
# 将stderr错误信息输出到/dev/null设备。
# 在Linux系统中,设备的读写跟文件读写一样,
# 写入/dev/null设备,就是写入黑洞,效果等于抑制错误信息输出。
$ command < pfile > ofile
# 将pfile作为命令的输入,将命令的stdout重定向到ofile,
# 注意没有重定向stderr。
更多关于重定向的技巧,参考exec命令设置重定向
小技巧,命令行清空文件的方法:
$ > <filename>
$ :> <filename>
$ cat /dev/null > <filename>
$ echo -n > <filename>
Windows的cmd也有重定向功能
D:\temp>ipconfig | findstr 192
D:\temp>ipconfig > a.txt
D:\temp>type a.txt
Windows的findstr
类似grep命令,type
类似cat命令。
>>
将左面命令的输出追加到文件,如果文件不存在,则创建。
$ echo '123' >> b.txt
$ cat b.txt
123
$ echo 'abc' >> b.txt
$ cat b.txt
123
abc
注意
<<
是bash的一个特殊用法,叫做 here document.
<<
$ cat << __eof
> this is here ducoment,
> hello.
> __eof
this is here ducoment,
hello.
__eof
在上例中表示结束字符串,可以任意设定,只要最后一行顶格输入这个字符串,here document就结束!Here Document内部支持变量替换,支持反斜杠转义,但是不支持通配符扩展,双引号和单引号也失去语法作用,变成了普通字符。
$ command << token
string
token
# 等同于
$ echo string | command
用here document编辑一个新文件:$ cat << __eof > kk.txt
用here document追加文件内容:$ cat << __eof >> kk.txt
<<<
将符号<<<
后面的内容,通过stdin传递给前面的命令。有些命令只从stdin接收输入,不接受命令行上其它参数作为输入。
$ cat <<< 'hi there'
# 等同于
$ echo 'hi there' | cat
$ md5sum <<< 'ddd'
# 等同于
$ echo 'ddd' | md5sum
md5sum命令没有string参数,传入string,只能通过重定向。
:
]bash中的冒号,就像python中的pass语句,一个语法占位符,什么都不干。冒号就是一个什么都不干的命令,它有如下作用:
function a() {
:
}
: << __eof
comment
comment
comment
...
__eof
冒号[:
]命令永远返回成功!
&
不想开太多terminal终端,或有一些进程本就适合后台运行.....有很多场景适合让一个进程后台运行,实现后台运行最简单的方式,就是在命令后面增加一个这个符号: &
$ command &
Windows的cmd窗口也可以后台启动进程,方法是
start /b command
~
和~+
~
会扩展出用户的home路径,~+
类似于pwd
命令:
$ echo ~
/home/xinlin
$ echo ~+
/mnt/c/Users/xinlin
$ echo ~root
/root
$ echo ~hoho
~hoho
如果遇到一个不存在的用户名,~
不起作用,原样输出。
|&
If
|&
is used, command1’s standard error, in addition to its standard output, is connected to command2’s standard input through the pipe; it is shorthand for2>&1 |
. This implicit redirection of the standard error to the standard output is performed after any redirections specified by the command.
|&
就是 2>&1 |
这就是把前一个命令的所有输出导入管道,给下一个命令。
参考:bash特殊变量
参考:bash各种括号
本文链接:https://cs.pynote.net/sf/linux/shell/202110161/
-- EOF --
-- MORE --