我不明白这行shell脚本。while 语句不需要设置 $ 的 'test' 或 [ ] 或 [[ ]] 表达式吗?为 1 还是 0?如何
while IFS= read -r -d $'\0'; do ...; done
去做?非常感谢您理解此处的语法的任何帮助。
我不明白这行shell脚本。while 语句不需要设置 $ 的 'test' 或 [ ] 或 [[ ]] 表达式吗?为 1 还是 0?如何
while IFS= read -r -d $'\0'; do ...; done
去做?非常感谢您理解此处的语法的任何帮助。
在 Bash 中,运行命令并将环境变量设置为(以及所有其他正常继承的环境变量)。因此,在将环境变量设置为空字符串(意味着没有字段分隔符)的情况下运行命令。varname=value commandvarnamevalueIFS= read -r -d $'\0'read -r -d $'\0'IFS
由于只要它成功读取输入并且没有遇到文件结尾就read返回成功(即设置$?为),因此总体效果是循环一组 NUL 分隔的记录(保存在变量中)。0REPLY
while 语句不需要设置 $ 的 'test' 或 [ ] 或 [[ ]] 表达式吗?为 1 还是 0?
testand [ ... ]and[[ ... ]]实际上不是表达式,而是命令。在 Bash 中,每个命令都返回成功(设置$?为0)或失败(设置$?为非零值,通常是1)。
(顺便说一下,正如上面评论中的nosid 所指出的那样,-d $'\0'相当于.Bash-d ''变量在内部表示为 C 样式/NUL 终止的字符串,因此您不能真正在字符串中包含 NUL;例如,echo $'a\0b'只打印a. )
我不明白这行shell脚本。while 语句不需要设置 $ 的 'test' 或 [ ] 或 [[ ]] 表达式吗?为 1 还是 0?[声明]如何做到这一点?
每个人都在回答关于-dandIFS=参数的问题,但没有人回答你关于testand的问题[[..]]。
所有标准 Unix 命令将在成功时返回零值,在退出时返回非零值。whileand语句使用该if值来确定是否继续循环:
假设您执行以下操作:
$ touch foo.txt #Create a "foo.txt" file
$ ls foo.txt
foo.txt
$ echo $?
0
$
请注意,该ls命令在退出时返回零。现在试试这个:
$ rm foo.txt
$ ls foo.txt
ls: foo.txt: No such file or directory
$ echo $?
1
$
如果foo.txt不存在,则该ls命令在退出时返回 1。
ifand命令对此while进行操作。
进入另一个终端窗口并创建一个foo.txt文件。然后回到原来的窗口试试这个:
$ while ls foo.txt > /dev/null
> do
> echo "The file foo.txt exists"
> sleep 2
> done
The file foo.txt exists
The file foo.txt exists
The file foo.txt exists
...
每两秒钟,while 将循环检查是否存在foo.txt并打印出该语句。现在,返回第二个终端窗口并删除foo.txt. 如果您返回第一个终端窗口,您会看到while循环结束。
您可以对以下内容执行相同操作if:
$ if ls foo.txt > /dev/null
> then
> echo "foo.txt exists"
> else
> echo "Whoops, it's gone!"
> fi
此if语句将打印foo.txt 存在或哎呀,它不见了!取决于目录中是否foo.txt存在名为的文件。
请注意if并while处理命令的返回退出值。根本不需要测试。
那么为什么要使用test,[...]和[[...]]语法呢?
假设您想知道是否$foo等于$bar。这就是test发挥作用的地方。试试这个:
$ foo=42
$ bar=42
$ test "$foo" -eq "$bar"
$ echo $?
0
$ bar=0
$ test "$foo" -eq "$bar"
$ echo $?
1
test 命令所做的只是在真实测试中返回零,在错误测试中返回非零值。这允许您在和语句中使用test命令。ifwhile
$ if test $foo -eq $bar
> then
> echo "foo is equal to bar"
> else
> echo "foo and bar are different"
> fi
foo and bar are different
$
那是什么[...]?
$ ls -il /bin/test /bin/[
10958 -rwxr-xr-x 2 root wheel 18576 May 28 22:27 /bin/[
10958 -rwxr-xr-x 2 root wheel 18576 May 28 22:27 /bin/test
第一列是inode。如果两个文件具有相同的inode,则它们是硬链接并引用同一个文件。请注意,它们在我的系统上都是 18,576 字节。
这[只是执行test命令本身的另一种方式。这两行是相同的:
if test $foo -eq $bar
if [ $foo -eq $bar ]
创建它[是为了使 shell 脚本看起来更好一些。但是,在下面,它正在运行一个命令,该命令将返回一个可以使用的零test或非零值。ifwhile
顺便说一句,在 Kornshell 和 BASH 中,[和test都内置在 shell 中。但是,它们确实引用了相同的内置命令。
这[[...]]是首次出现在 Kornshell 中的测试的特殊版本。它允许使用模式匹配,并且速度更快,因为它不会产生另一个进程来运行test命令。
代码说明:
IFS=将 IFS 设置为 null(输入字段分隔符)read使用以下选项读取当前行的命令:-r: 不允许反斜杠转义任何字符-d继续直到读取 DELIM 的第一个字符,而不是换行$'\0'零字节(ASCII NUL 字符)看
help read
不,test命令和[[ ...]]表达式只是提供退出状态(唯一while关心的事情)的构造,它反映了它包含的条件表达式的真实性。
例如,如果值为,则退出状态[[ $foo = bar ]]为 0(成功),否则为非零存在状态(具体为 1)。$foobar
while只要while关键字后面的命令的退出状态为 0,循环就会执行其主体。在此代码中,只要read它可以从其输入中读取某些内容,则退出状态为 0。