我是bash脚本的初学者,我在遵循脚本时遇到问题。
我想处理来自标准的所有给定参数。然后我检查这些参数是否是普通的文本文件。如果是,我想将它们存储到数组中,稍后我想遍历整个数组。但是我收到一个错误:单词未扩展在带有文件+=("$@") 的行上我试着像这样写 file=("$@")但随后我在行上收到以下错误:"("意外(期望"fi")
我将不胜感激任何建议。提前谢谢你。
for file in "${argv[@]}"; do
if [ -d "$file" ]
then
echo "Error: '"$file"' is directory!" > /dev/stderr
continue
fi
if [[! -f "$file"] || [! -r "$file"]]
then
echo "Error: '"$file"'!" > /dev/stderr
continue
fi
file "$file" | grep text >& /dev/null
if [ ! $status ]
then
files+=("$@")
else
echo "Error: '"$file"' not a text file!" > /dev/stderr
fi
done
for file in "${files[@]}"; do
# .....
done
尝试这样做:
#!/bin/bash
files=( )
for file; do
if ([[ -f "$file && -r "$file" ]] && file "$file" | grep -q -i "text"); then
files+=( "$file" )
fi
done
for f in ${files[@]}; do
# something with "$f"
done
另一个版本,具有错误处理:
#!/bin/bash
files=( )
for file; do
if [[ ! -f "$file ]]; then
echo >&2 "$file is not a regular file"
continue
fi
if [[ ! -r "$file ]]; then
echo >&2 "$file is not readable for $USER"
continue
fi
if ! file "$file" | grep -q -i "text"; then
echo >&2 "$file is not a text file"
continue
fi
files+=( "$file" )
done
for f in ${files[@]}; do
# something with "$f"
done
注意
-
argv
在bash
中不存在,for file
就足够了 - 不使用不存在的变量
$status
,而是使用预定义的变量$?
- 无需测试最后状态,您可以做一些更短的事情,例如
grep -q pattern file && do_something
-
echo >&2
的意思是重定向到STDERR
这是我刚刚编写的脚本,似乎按照您的要求进行操作......只需替换..在第三次测试中,无论您需要什么。不幸的是,我从来没有像你上面那样使用数组,所以我只是按照我的方式写的。我希望它有所帮助。只需将其作为 bash {scriptname}.sh 运行即可。任何输入标准的内容都将处理。
#!/bin/bash
checkfile()
{
for i in $token
do
if [ -f "${i}" ]; then
{
echo "It's a file"
}
elif [ -d "${i}" ]; then
{
echo "It's a directory"
}
elif [ -z "${i}" ]; then
{
:
}
fi
done
}
while ( : )
do
read token
checkfile
sleep 2
done
以下是 bash 中的调试输出:
+ read token
a
+ checkfile
+ for i in '$token'
+ '[' -f a ']'
+ '[' -d a ']'
+ echo 'It'''s a directory'
It's a directory
+ sleep 2
+ :
+ read token
b
+ checkfile
+ for i in '$token'
+ '[' -f b ']'
+ echo 'It'''s a file'
It's a file
+ sleep 2
+ :
+ read token
a
+ checkfile
+ for i in '$token'
+ '[' -f a ']'
+ '[' -d a ']'
+ echo 'It'''s a directory'
It's a directory
+ sleep 2
+ :
+ read token
Sputnick的回答是一个很好的解决方案。如果您想坚持自己的实现,请确保更正以下行:
if [[! -f "$file"] || [! -r "$file"]]
应始终在括号和测试表达式之间留空格:[[ ! -f "$file" ]]
。此外,由于您使用的是 ||
运算符,请使用双括号而不是单括号:
if [[ ! -f "$file" ]] || [[ ! -r "$file" ]]
将行files+=("$@")
更改为 files+=( "$file" )
或 files[${#files[@]}]="$file"
。
不确定您要对status
变量执行什么操作。测试[ ! $status ]
将返回 True 对于未赋值的status
、赋值的变量(如 status=
或任何status=$(command >& /dev/null)
)。如果要针对 file ...
命令的退出状态进行测试,请使用整数测试而不是字符串比较:if [ $? -eq 0 ]
或 if (($? == 0))
。