
您每天都使用外壳吗? 准备解决一些逻辑问题并学习新知识吗? 欢迎来到猫。
这里介绍的某些任务不会带来真正的好处,因为它们会影响某些复杂的边界情况。 另一部分对于经常使用该shell并阅读其他人的脚本的用户很有用。
注意:在撰写本文时,作者在Windows 10的Linux子系统中使用了bash 4.4.12(1)-release。任务的复杂性不同。
输入/输出流
任务1$ cat 1 The cake is a lie! Wanted! Cake or alive $ cat 1 | head | tail | sed -e 's/alive/dead/g' | tee | wc -l > 1
命令后文件1中有几行?
解说在解释了命令之后,但是在运行所有程序之前,bash与指定的输入/输出流一起工作。 因此,在启动第一个程序之前将文件1
清除,并且cat
打开已经清除的文件。
任务2 $ cat file1 I love UNIX! $ cat file2 I don't like UNIX $ cat file1 <file2
屏幕上将显示什么?
任务3 $ cat file Just for fun $ cat file 1>&2 2>/dev/null
屏幕上将显示什么?
解说有一个误解,认为序列
1>&2
将第一个线程重定向到第二个线程,但是事实并非如此。 从任务中考虑团队。 在解释输入的命令开始时,流表如下所示:
bash检测序列
1>&2
并将单元2的内容复制到单元1:
在检测到序列
2>/dev/null
解释器将值写入单元格2,其他单元格则保持不变:
bash还显示错误流,以便我们在屏幕上找到文件的文本。
任务4如何将stdout输出发送到stderr,如何将stderr输出发送到stdout?
解说该原理与上一个任务完全相同。 这就是为什么我们需要额外的流来临时存储的原因。
可执行文件
任务5给定文件test.sh
执行以下命令:
$ ls 1 2 3 test.sh $ ./test.sh 1 2 3
脚本将输出什么?
答案1 2 3
1 2 3
ls: cannot access '1 2 3': No such file or directory
1 2 3
解说没有引号,变量$ *和$ @相同,并被扩展为脚本的所有给定位置参数,并用空格分隔。 在引号中,公开方法更改:$ *变为“ $ 1 $ 2 $ 3”,而$ @依次变为“ $ 1”“ $ 2”“ $ 3”。 由于文件“ 1 2 3”不在目录中,因此ls显示错误
任务6在当前目录中,创建一个权限为755且具有以下内容的
-c
文件:
将$ PATH变量清零,然后尝试执行:
$ PATH= $ -c "echo SURPRISE"
屏幕上将显示什么? 如果您重新输入最后一条命令会怎样?
答案第一次将显示SURPRISE
,第二次将显示echo SURPRISE
解说如果PATH为空,则Shell将开始在当前目录中搜索文件。 -c刚刚位于。 由于可执行文件是文本文件,因此以shebang为主题读取第一行。 团队根据模板组装:
<shebang> <filename> <args>
因此,在执行之前,我们的命令如下所示:
/bin/bash -c "echo SURPRISE"
结果,这完全不是我们想要做的。
如果您第二次执行它,那么外壳程序将从缓存中获取有关-c的信息并正确执行它。 保护自己免受这种意外影响的唯一方法是在shebang上增加两个负号。
变数
任务7 $ ls file $ cat <$(ls) $ cat <(ls)
第一种和第二种情况将显示什么?
答案第一个将显示文件文件的内容,第二个将显示文件名。
解说在第一种情况下,执行替换
cat <file
在第二种情况下,
<(ls)
将由一个命名管道替换,该命名管道由输入连接到stdout ls和来自stdin cat的输出连接。
替换后,命令将采用以下形式:
cat /dev/fd/xx
任务8 $ TEST=123456 $ echo ${TEST%56}
屏幕上将显示什么?
解说有了这样的记录,模式匹配(#-从变量的开头; ##-从变量的开头贪婪;%-从变量的结尾贪婪; %%-从变量的结尾贪婪地),并且在替换时将其删除。 变量的内容保持不变。 因此,例如,方便地获取不带扩展名的文件名。
$ TEST=file.ext $ echo ${TEST%.ext} file
任务9 $ echo ${friendship:-magic}
屏幕上将显示什么?
答案如果定义了友谊变量,则变量的内容。 否则,魔术。
解说在文档中,此魔术称为“未设置或为空”,并且允许您在一行中使用变量的指定默认值。
执行顺序
任务10 while true; false; do echo Success done
屏幕上将显示什么?
解说while和if语句允许您将整个动作序列塞入条件中,但是仅在最后一条命令中才考虑结果(返回码)。 由于它为假,因此循环甚至不会开始。
任务11 $ false && true || true && false && echo 1 || echo 2
屏幕上将显示什么?
解说考虑到只考虑了最后一条命令的返回码,请添加括号以使命令明确并简化命令:
((((false && true) || true) && false) && echo 1) || echo 2 (((false || true) && false) && echo 1) || echo 2 ((true && false) && echo 1) || echo 2 (false && echo 1) || echo 2 false || echo 2 echo 2
评论,建议和其他任务在评论或PM中受到欢迎。