首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >shell脚本代码-无法理解

shell脚本代码-无法理解
EN

Stack Overflow用户
提问于 2014-03-27 14:30:11
回答 4查看 100关注 0票数 0

我想了解这段代码,因为我是shell脚本的初学者。

代码语言:javascript
运行
复制
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
  1. 为什么我们使用第1行和第2行?
  2. 我刚刚学到了其他的结构 如果那样的话

我们不能把第6-7行转换成那种结构吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 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脚本的顶部,并完全摆脱包装器来实现这一点:

代码语言:javascript
运行
复制
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/下。

票数 1
EN

Stack Overflow用户

发布于 2014-03-27 14:35:21

第1行不应该缩进;第一个字符应该是#。在本例中,它告诉内核使用命名解释器/bin/bash执行该程序。如果您愿意,可以将任何可执行文件(而不是脚本)指定为解释器。

第2行是防范荒谬;如果有人在没有/bin/usr/bin的情况下设置了路径,那么他们已经遇到了某种麻烦。然而,这确保了他们的存在。(但请注意,在Solaris上,/bin是指向/usr/bin的符号链接,因此在$PATH中不需要这两种链接,但其中一种肯定应该存在。)

是的,您可以将第6-7行转换为:

代码语言:javascript
运行
复制
if [ -f "$TMP_FILE" ]
then exit
fi
touch "$TMP_FILE"

如果系统上只有一个用户,那么您选择的锁文件名就足够了,但它不适合更广泛使用的程序(两个人不能同时使用该文件)。

可以通过添加trap命令来清理临时文件,从而改进代码:

代码语言:javascript
运行
复制
trap "rm -f '$TMP_FILE'; exit 1" 0 1 2 3 13 15
…commands…
rm -f "$TMP_FILE"
trap 0

如果程序崩溃或被中断,这将删除临时文件。

票数 1
EN

Stack Overflow用户

发布于 2014-03-27 14:40:04

  1. 第一行是所谓的谢邦.它告诉任何试图运行文件的人如何运行它。第二行通过将/bin/usr/bin附加到该变量以确保x$PATH上,因此,如果x位于这两个目录之一(或$PATH中的其他目录),那么运行简单的命令x就可以工作。
  2. 第6行和第7行实际上没有任何关系。第6行本身可以转换为if语句: 如果-f $TMP_FILE退出fi
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22690670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档