本文摘录自 Linux 命令行
当你输入一行命令并按下 enter 键,bash 会在执行你的命令之前对输入的字符完成几个步骤的处理。比如“*”,是字符展开以及其他的路径名展开、花括号展开、波浪线展开等。
1. * 展开
echo this is a test 控制台就会输出echo 后的字符。
echo A* 控制台会输出以大写字母A开头的目录
echo *s 输出以小写字母结尾的目录
如果要显示隐藏文件,直接 echo .*
会将 “.”,"…"也匹配出来,因为它扫描的是当前目录和父级目录,ls -d .[!.]?*
可以实现,它匹配的是以圆点开头,第二个字母不包含圆点,且至少包含一个字符,这个命令将正确列出大多数的隐藏文件。ls -A
则可以列出所有的隐藏文件。
2. 波浪线展开:echo ~ 将展示指定用户的主目录
3. 花括号展开:
如下
echo Front-{A,B,C}-Back
打印出:Front-A-Back Front-B-Back Front-C-Back,花括号前面的是前言,结尾叫附言,花括号表达式本身可能包含一个由逗号分隔开的字符串列表。echo {1..5}
控制台输出:1 2 3 4 5echo {z..a}
输出:z y x w v u t s r q p o n m l k j i h g f e d c b aecho a{A{1,2},B{3,4}}b
花括号嵌套会输出:aA1b aA2b aB3b aB4b;这个有什么用呢?最常见的应用是创建一系列的文件或目录列表。如我们要将大量相片按照年月先后组织起来,首先要创建一系列“年-月”的形式命名的目录。
mkdir Pics
cd Pics
# 中间的空格会将命令当成两个使用,就是或的意思,mkdir和 echo 都是,花括号至少得有2个元素才能实现匹配,否则就会产生{X}这样的目录
mkdir {2020..2022}-0{1..9} {2020..2022}-{10..12}
4. 命令替换:可以使用一个命令的输出作为另一个命令的一部分来使用
如下:
echo $(ls)
:输出当前目录ls -l $(which cp)
🖨-rwxr-xr-x 1 root wheel 152672 3 26 15:21 /bin/cp 这里把 which cp 的执行结果作为一个参数传递给 ls命令,因此可以在 ls 不知道完整路径名的情况下获得文件列表属性。其他类似命令也可以使用,如file $(ls /usr/bin/* | grep zip)
等。
5. 引用
前面我们知道了 shell 有多种方式展开命令,现在该学习怎么控制展开了。
echo this is a test
🖨this is a test 会自动过滤空格localhost:2020-01 chappyzhao$
🖨the total is 00.00 参数展开把 $1 的值替换为了一个空字符串,因为 1 是没有定义的变量。- 针对上述情况,shell 提供了一种叫做引用的机制,来选择性的禁止不需要的展开:
"" '' \
。(就是双引号、单引号和转义字符) - 双引号:如果你把文本放在双引号中,shell 使用的特殊字符都将失去它们的特殊含义,而被当作普通字符来看待。有几个例外:
$ \
和倒引号`。这意味着单词分割、路径名展开、 波浪线展开和花括号展开都将失效,然而参数展开、算术展开和命令替换 仍然执行。echo $(cal)
🖨五月 2022 日 一 二 三 四 五 六 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 没有引用的命令替换导致命令行包含 38 个参数-
echo "$(cal)" # 命令行只有一个参数,参数中包含嵌入的的空格和换行符 五月 2022 日 一 二 三 四 五 六 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
- 单引号:如果我们要禁止所有的命令展开,可以用单引号。
-
# 下面是无引号、双引号和单引号的区别 localhost:2020-01 chappyzhao$ echo text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER text /Users/chappyzhao/*.txt a b foo 4 chappyzhao localhost:2020-01 chappyzhao$ echo "text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER " text ~/*.txt {a,b} foo 4 chappyzhao localhost:2020-01 chappyzhao$ echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER ' text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER
-
- 转义字符:在字符前加一个反斜杠就可以引用字符,使用转义字符可以有选择的阻止展开。
echo "The balance for user $USER is: \$5.00"
:The balance for user chappyzhao is: $5.00