2013-07-17 117 views
1

我需要一个脚本来保持轮询“receive_dir”目录,直到“stopfile”被写入目录。shell脚本中的“一元运算符”

尽管有空目录,但仍必须运行。

到目前为止,我有这个,但如果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 
+2

http://mywiki.wooledge.org/ParsingLs。此外,双引号的变量,以避免[分词](http://mywiki.wooledge.org/BashGuide/Practices#Quoting) – user000001

回答

1

你没有计算任何东西,'测试'无法评估它。

~> [ $empty_var = stopfile ] 
-bash: [: =: unary operator expected 

首先,不要解析LS:

http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29

编辑:部分的问题是你的循环实际上是在做试验,尝试这样的事情(假设receive_dir是相对的):

@ user000001是对的;我原来觉得例如将遭受同样的问题,所以这个:

for i in receive_dir/* 
do 
    time=$(date +%m-%d-%Y-%H:%M:%S) 
    echo $time 
    echo $i 
    [ $i = stopfile ] && break 
done 

编辑:添加在另一个例子中根据您的评论:

这个怎么样...

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 
+0

事实上,我同意。我承认我宁愿用'[[$ i == stopfile]]来处理它,以防止由命令替换引起的问题,但他使用ksh,我认为不能使用'[[]] '语法。 –

+0

此外,@ user000001,+1您的反馈 - 欢呼:) –

+1

'[[]]'在这两个bash和ksh的一个内置。 – Yossarian

5

这将做你所要求的(循环直到停止文件存在)。我添加了“睡眠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 
2

如果你有空目录,该

until [ $i = stopfile ] 

被评估为

until [ = stopfile ] 

什么是ofcourse语法错误。

一个注释:永远不要从ls解析输出。

#!/bin/bash 

do_something() { 
    echo $(date +%m-%d-%Y-%H:%M:%S) "$1" 
} 

dir="." 
until [[ -f "$dir/stopfile" ]] 
do 
    find "$dir" -print0 | while IFS= read -r -d '' filename 
    do 
     do_something "$filename" 
    done 
done 

或(慢得多)

do_something() { 
    echo $(date +%m-%d-%Y-%H:%M:%S) "$1" 
} 
export -f do_something 

dir="." 
until [[ -f "$dir/stopfile" ]] 
do 
    find "$dir" -exec bash -c 'do_something "{}"' \; 
done 
+0

我还需要呼应文件在receive_dir中。 – iaav

+0

@iaav不明白。 'do_someting'输出日期和文件名。如果你需要在一个单独的行,只需添加另一种回声...... – jm666

+0

“出口-f”不会在Korn shell中运行。 :( – iaav

0

另一种选择是使用inotifywait监视目录的状态。例如,该脚本将运行循环,直到触摸文件“stopfile”。

until inotifywait "receive_dir" | grep "stopfile" 
do 
    echo "running" 
done 
echo "done" 

的优点是,这些没有繁忙的循环,而且你不必反复调用(潜在的昂贵)find命令