bash shell 脚本中的“期望一元运算符”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17707499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
“unary operator expected” in shell script
提问by iaav
I need a script to keep polling "receive_dir" directory till "stopfile" get written in the directory.
我需要一个脚本来继续轮询“receive_dir”目录,直到“stopfile”被写入目录。
This has to run despite empty directory.
尽管目录为空,但它必须运行。
So far i have this but fails if receive_dir is empty with no files with "unary operator expected". Help !!
到目前为止,我有这个,但如果 receive_dir 为空并且没有带有“一元运算符预期”的文件,则失败。帮助 !!
#!/usr/bin/ksh
until [ $i = stopfile ]
do
for i in `ls receive_dir`; do
time=$(date +%m-%d-%Y-%H:%M:%S)
echo $time
echo $i;
done
done
回答by Anders Martinsson
This will do what you ask for (loop until the stop file exist). I added a "sleep 1" to lower resource usage. It's also good practice to use "#!/usr/bin/env ksh" as shebang.
这将执行您的要求(循环直到停止文件存在)。我添加了“睡眠 1”以降低资源使用率。使用“#!/usr/bin/env ksh”作为shebang也是一个好习惯。
#!/usr/bin/env ksh
until [ -e receive_dir/stopfile ]
do
time=$(date +%m-%d-%Y-%H:%M:%S)
echo $time
sleep 1
done
回答by jm666
If you have empty dir, the
如果您有空目录,则
until [ $i = stopfile ]
is evaluated as
被评估为
until [ = stopfile ]
what is ofcourse syntax error.
什么是当然的语法错误。
One comment: Never parse output from ls.
一条评论:永远不要解析来自ls.
#!/bin/bash
do_something() {
echo $(date +%m-%d-%Y-%H:%M:%S) ""
}
dir="."
until [[ -f "$dir/stopfile" ]]
do
find "$dir" -print0 | while IFS= read -r -d '' filename
do
do_something "$filename"
done
done
or (much slower)
或(慢得多)
do_something() {
echo $(date +%m-%d-%Y-%H:%M:%S) ""
}
export -f do_something
dir="."
until [[ -f "$dir/stopfile" ]]
do
find "$dir" -exec bash -c 'do_something "{}"' \;
done
回答by das.cyklone
You're evaluating nothing, and the 'test' isn't able to evaluate it.
您没有评估任何内容,而“测试”无法评估它。
~> [ $empty_var = stopfile ]
-bash: [: =: unary operator expected
First, don't parse ls:
首先,不要解析 ls:
http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29
http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29
EDIT: Part of the issue is your loop is actually doing the test, try something like this (assuming receive_dir is relative):
编辑:问题的一部分是你的循环实际上是在做测试,尝试这样的事情(假设 receive_dir 是相对的):
@user000001 is right; my original find example would suffer the same issue, so this:
@user000001 是对的;我原来的 find 例子会遇到同样的问题,所以这个:
for i in receive_dir/*
do
time=$(date +%m-%d-%Y-%H:%M:%S)
echo $time
echo $i
[ $i = stopfile ] && break
done
EDIT: Adding in another example based on your comment:
编辑:根据您的评论添加另一个示例:
How about this...
这个怎么样...
FOUND="N"
while [ "${FOUND}" = "N" ]
do
for i in receive_dir/*
do
time=$(date +%m-%d-%Y-%H:%M:%S)
echo $time
echo $i
[ "$i" = stopfile ] && FOUND="Y"
done
sleep 60
done
回答by user000001
Another option is to use inotifywaitto monitor the status of the directory. For example, this script will run the loop until the file "stopfile" is touched.
另一种选择是用来inotifywait监视目录的状态。例如,此脚本将运行循环,直到触及文件“stopfile”。
until inotifywait "receive_dir" | grep "stopfile"
do
echo "running"
done
echo "done"
The advantage is that these is no busy loop, and that you don't have to repeatedly call the (potentially expensive) find command
优点是这些不是忙循环,并且您不必重复调用(可能很昂贵) find 命令

