Nov*_*ser 44 shell shell-script
为什么下面的脚本不会执行,而是给出一个语法错误else
:
LOGS3_DIR=~/logs
if [ -d "$LOGS3_DIR" ]; then
cd
cd "$LOGS3_DIR"
echo "$LOGS3_DIR"
for filename in `find "." -mtime 1 -type f`
do
if lsof "$filename" > /dev/null
then
# file is open
else
echo "deleting $filename"
rm "$filename"
fi
done
fi
Run Code Online (Sandbox Code Playgroud)
cuo*_*glm 109
如果文件已打开,您似乎想执行无操作,因此您应该添加一个:
,它是 中的一个空命令bash
:
if lsof "$filename" > /dev/null; then
# file is open
:
else
printf 'deleting %s\n' "$filename"
rm -- "$filename"
fi
Run Code Online (Sandbox Code Playgroud)
如果您不使用:
,bash
则无法解析您的代码,并且会显示类似bash: syntax error near unexpected token 'else'
.
Jos*_* R. 27
另一种选择:颠倒你的逻辑。
if ! lsof "$filename" >/dev/null;then
echo "deleting $filename"
rm "$filename"
fi
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 24
不要在find
. 在这里,一切都可以通过find
:
find . -mtime 1 -type f ! -exec lsof -t {} \; -exec rm -f {} \; > /dev/null
Run Code Online (Sandbox Code Playgroud)
随着一些find
实现(包括FreeBSDfind
来自何方和GNU find
),你可以使用-delete
的替代-exec rm...
。
您收到错误的原因是,在then
和之间没有命令,else
并且某些 shell(从该语法来自的 Bourne shell 开始)需要至少一个(并且注释不是命令)。请注意,这完全是任意的,并且没有理由为什么这些 shell 会这样做。yash
并且zsh
没有那个限制(if false; then else echo x; fi
甚至if false; then else fi
可以与它们一起工作)。
正如其他人所说,您可以使用像:
(or for nothing in; do nothing; done
)这样的 noop 命令或使用!
关键字反转逻辑(在 POSIX shell 中可用,但在 Bourne shell 中不可用(您会发现:
在该 shell中使用for that 很常见))。mksh
并且yash
碰巧支持if false; then () else echo x; fi
(我不会依赖它,因为这可能会在未来的版本中改变)。
另一种方法是:
lsof... || {
cmd1
cmd2
}
Run Code Online (Sandbox Code Playgroud)
虽然一个区别是整体退出状态,这将是lsof
iflsof
失败。
Cod*_*ome 19
其他答案都没有真正解决您最初的问题,即为什么命令会出现语法错误。这是由then和else之间缺少命令引起的。
您的原始代码如下所示:
if lsof "$filename" > /dev/null
then
# file is open
else
echo "deleting $filename"
rm "$filename"
fi
Run Code Online (Sandbox Code Playgroud)
问题是您在then和else之间有一个注释,但该注释不被视为命令。简而言之,您可以按如下方式重写您遇到的问题(从结构上讲):
$ if true; then else echo; fi
bash: syntax error near unexpected token `else'
Run Code Online (Sandbox Code Playgroud)
您可以通过在else之前放置实际命令来解决此问题,但单独添加注释是行不通的。的IF-THEN部分不能为空; 如果你想要一个占位符,你可以使用内置的冒号。例如:
$ if true; then :; else echo; fi
Run Code Online (Sandbox Code Playgroud)
只需放入then和else:
之间的部分即可修复您遇到的语法错误。