这给了我一个错误,说参数太多:
if [ $( file -b $i ) == "directory" ]
但是当我尝试这个时
name=$( file -b $i )
if [ name == "directory" ]
看起来效果很好。
有人可以解释这一点或在文档中指出解释吗?
答案1
有几个问题:
]
[
表示( )参数的结束test
,并且它必须是最后一个参数;你有几个]
s,这是错误的;大概你的意思是使用:if [ $( file -b $i ) == "directory" ]
如果您使用了上面的内容,您会得到
bash: [: too many arguments
,因为分词将在变量扩展 ( ) 的输出上完成$i
,然后进行命令替换$()
(file
command) ,并且[
会在 之前看到多个单词=
,从而导致错误消息。您需要引用变量扩展和命令替换:[ "$(file -b "$1")" == "directory" ]
作为旁注,您应该使用bash
关键字[[
,而不是[
因为前者将为您处理单词拆分(和路径名扩展)。
答案2
if [ $( file -b $i ) == "directory" ]
这里有两个问题:
使用 single
=
进行字符串比较。请man test
参阅 正确的语法(注意,在许多情况下都有特定于 shell 的实现,因此如果您没有相关文档,[
请参阅您的 shell 的语法)。如果您绝对需要,请使用它,这是许多类似 bourne shell 的功能,包括 bash、ksh、zsh。注意: while存在于 bash 中man page
test
==
[[
==
从2.0版本开始, “= 应与测试命令一起使用以实现 POSIX 一致性。” (bash 手册页)。将所有变量引用为
"$()"
.特别感兴趣的是$i
。$i
由于 shell 的单词扩展,带空格的文件名会分成多个单词。
例子:
bash-4.3$ mkdir with\ space
bash-4.3$ i="./with space"
bash-4.3$ set -x
bash-4.3$ [ $( file -b $i ) == "directory" ] && echo "YES"
++ file -b ./with space
+ '[' cannot open '`./with'\''' '(No' such file or 'directory)' cannot open '`space'\''' '(No' such file or 'directory)' == directory ']'
bash: [: too many arguments
name=$( file -b $i )
if [ name == "directory" ]
这里的问题:
name
没有扩展到变量,这里只是一个字符串“名称”。你需要"$name"
再一次,单身=
另外,它不可能起作用,因为 的退出状态test
返回为 false(退出状态 1)
$ name=$(file -b /etc)
$ set -x
$ [ name == "directory" ]
+ '[' name '==' directory ']'
$ echo $?
+ echo 1
1
以上在bash
和mksh
shell 上进行了测试。
答案3
有很多问题!让我们看一下正在“工作”的部分:
name=$( file -b $i )
if [ name == "directory" ]
这将 file 命令的输出分配给名为 的变量name
,但不使用它;相反,它运行[
带有 3 个参数的命令:name
、==
和directory
。接受==
是 bash 扩展。
如果将其更正为使用$name
而不是,在许多情况下name
您会再次遇到问题。too many arguments
这是因为file
返回多个单词结果,例如ASCII text
.所以命令运行后你会得到
if [ ASCII text == directory ]
现在很明显该命令缺少一些分组。
if [ "$(file -b -- "$i")" = "directory" ]
可能是您想要的:=
而不是==
为了可移植性,并引用命令替换的结果你几乎总是想做的事。