我想了解这段代码,因为我是shell脚本的初学者。
1 #!/bin/bash
2 PATH=$PATH:/bin:/usr/bin
3
4
5 TMP_FILE=/tmp/i_am_running
6 [ -f $TMP_FILE ] && exit
7 touch $TMP_FILE
8
9
10 /usr/bin/python /home/ahmed/Desktop/python.py
11 rm $TMP_FILE
我们不能把第6-7行转换成那种结构吗?
发布于 2014-03-27 14:40:17
我要一条条地走:
1:这似乎是一个缺陷:在#之前不应该有空格。不管怎么说,这是一条“谢邦线”,它告诉我们要使用什么解释器。有些人更希望看到#!/usr/bin/env bash
,如果用户希望在非默认版本bash下运行,它会提供更大的灵活性。
5:创建一个包含路径的变量。
6:[ -f $TMP_FILE ] && exit
的意思是“如果文件存在,退出(使用成功代码,即0)”。你说得对,它可以写成"if“语句。还请注意,[ -f $TMP_FILE ]
实际上是test -f $TMP_FILE
的缩写;知道了这一点,您可以查看man test
来查看各种选项。
7:既然我们知道文件不存在,就创建它。或者至少我们尝试--这可能由于各种原因而失败,并且返回代码没有被检查!将set -e
放在任何shell脚本的顶部是很好的做法,这意味着“如果有未检查的失败代码就停止”。
10:接下来我们运行Python。不是用户选择Python解释器,特别是/usr/bin/。同样,这也不是最佳实践--最好是在Python本身的顶部有一个#!/usr/bin/env python
shebang行,并直接调用它,从而允许用户的环境选择所需的Python解释器。
11:现在我们删除了$TMP_FILE,这将允许我们下次再次运行。因此,它是一种“锁文件”,虽然不是一个非常健壮的实现文件。例如,如果用户在Python脚本运行时按下Ctrl来中断脚本,会发生什么?锁文件将被留下。在本例中,您可以在退出之前使用Bash中的trap
内置程序删除锁文件。
也许您应该直接在Python中集成锁文件功能,并去掉这个包装脚本。您可以通过将它放在Python脚本的顶部,并完全摆脱包装器来实现这一点:
import errno
import fcntl
import sys
lockfile = open('/tmp/i_am_running', 'a')
try:
fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError as ex:
if ex.errno == errno.EWOULDBLOCK:
sys.exit("oops, already running")
else:
raise
# now the file is locked, do whatever you need and it will unlock on exit
最后,请注意,在Linux系统上,这样的锁文件的规范位置是在/var/run/
下,而不是在/tmp/
下。
发布于 2014-03-27 14:35:21
第1行不应该缩进;第一个字符应该是#
。在本例中,它告诉内核使用命名解释器/bin/bash
执行该程序。如果您愿意,可以将任何可执行文件(而不是脚本)指定为解释器。
第2行是防范荒谬;如果有人在没有/bin
和/usr/bin
的情况下设置了路径,那么他们已经遇到了某种麻烦。然而,这确保了他们的存在。(但请注意,在Solaris上,/bin
是指向/usr/bin
的符号链接,因此在$PATH
中不需要这两种链接,但其中一种肯定应该存在。)
是的,您可以将第6-7行转换为:
if [ -f "$TMP_FILE" ]
then exit
fi
touch "$TMP_FILE"
如果系统上只有一个用户,那么您选择的锁文件名就足够了,但它不适合更广泛使用的程序(两个人不能同时使用该文件)。
可以通过添加trap
命令来清理临时文件,从而改进代码:
trap "rm -f '$TMP_FILE'; exit 1" 0 1 2 3 13 15
…commands…
rm -f "$TMP_FILE"
trap 0
如果程序崩溃或被中断,这将删除临时文件。
https://stackoverflow.com/questions/22690670
复制相似问题