标签: shell-script

如何让 bash 以与 pipefail 类似的方式在反引号失败时退出?

所以我喜欢尽可能地强化我的 bash 脚本(并且当不能委托给像 Python/Ruby 这样的语言时)以确保错误不会被发现。

在这种情况下,我有一个 strict.sh,其中包含以下内容:

set -e
set -u
set -o pipefail
Run Code Online (Sandbox Code Playgroud)

并在其他脚本中获取它。然而,虽然 pipefail 会出现:

false | echo it kept going | true

它不会拿起:

echo The output is '`false; echo something else`' 
Run Code Online (Sandbox Code Playgroud)

输出将是

输出是''

False 返回非零状态和非标准输出。在管道中它会失败,但在这里没有发现错误。当这实际上是存储在变量中的计算供以后使用,并且该值设置为空白时,这可能会导致以后出现问题。

那么 - 有没有办法让 bash 将反引号内的非零返回码视为足以退出的理由?

bash shell-script

73
推荐指数
6
解决办法
3万
查看次数

通过分隔符的第一次出现拆分字符串

我有一个下一个格式的字符串

id;some text here with possible ; inside
Run Code Online (Sandbox Code Playgroud)

并希望通过第一次出现 将其拆分为 2 个字符串;。所以,它应该是:idsome text here with possible ; inside

我知道如何拆分字符串(例如,使用cut -d ';' -f1),但由于我;在左侧部分,因此它将拆分为更多部分。

bash string shell-script split

73
推荐指数
5
解决办法
19万
查看次数

Bash:如果 command1 失败,则运行 command2

我想做这样的事情:

if cmd1 && cmd2
echo success
else
echo epic fail
fi
Run Code Online (Sandbox Code Playgroud)

我该怎么做?

bash shell-script exit-status

72
推荐指数
3
解决办法
7万
查看次数

用下划线连接两个变量

我需要连接两个变量来创建一个带有下划线的文件名。让我们调用我的变量$FILENAME以及$EXTENSION从文件中读取文件名的位置。

FILENAME=Hello
EXTENSION=WORLD.txt
Run Code Online (Sandbox Code Playgroud)

现在...

我尝试了以下但没有成功:

NAME=${FILENAME}_$EXTENSION
NAME=${FILENAME}'_'$EXTENSION
NAME=$FILENAME\\_$EXTENSION
Run Code Online (Sandbox Code Playgroud)

我总是得到某种奇怪的输出。通常下划线在前。

我需要它

echo $NAME
Hello_WORLD.txt
Run Code Online (Sandbox Code Playgroud)

bash shell-script

72
推荐指数
2
解决办法
18万
查看次数

正确锁定 shell 脚本?

有时您必须确保同一时间只有一个 shell 脚本实例正在运行。

例如,通过 crond 执行的 cron 作业本身不提供锁定(例如默认的 Solaris crond)。

实现锁定的常见模式是这样的代码:

#!/bin/sh
LOCK=/var/tmp/mylock
if [ -f $LOCK ]; then            # 'test' -> race begin
  echo Job is already running\!
  exit 6
fi
touch $LOCK                      # 'set'  -> race end
# do some work
rm $LOCK
Run Code Online (Sandbox Code Playgroud)

当然,这样的代码有竞争条件。有一个时间窗口,其中两个实例的执行都可以在第 3 行之后才能访问$LOCK文件。

对于 cron 作业,这通常不是问题,因为两次调用之间有几分钟的间隔。

但是事情可能会出错——例如,当锁定文件在 NFS 服务器上时——挂起。在这种情况下,多个 cron 作业可以在第 3 行阻塞并排队。如果NFS服务器再次处于活动状态,那么你已经惊群并行运行的作业。

在网上搜索我发现工具lockrun似乎是该问题的一个很好的解决方案。使用它,您可以运行一个需要像这样锁定的脚本:

$ lockrun --lockfile=/var/tmp/mylock myscript.sh
Run Code Online (Sandbox Code Playgroud)

您可以将其放在包装器中或从您的 crontab 中使用它。

lockf()如果可用,它使用(POSIX) 并回退到flock()(BSD)。并且lockf()对 NFS …

cron nfs shell-script coreutils lock

71
推荐指数
6
解决办法
6万
查看次数

shell 脚本中缩进的标准是什么?

Java 社区使用 4 个空格作为缩进单位。1
Ruby 社区使用 2 个普遍认可的空间。2

shell 脚本中缩进的标准是什么?2 或 4 个空格或 1 个制表符?

standard shell-script indentation

70
推荐指数
3
解决办法
7万
查看次数

通过符号链接执行时获取当前脚本的路径

我有一个实用程序,由几个目录组成,其中包含一些 bash 脚本和支持文件,这些文件将部署到多台机器上,可能在每台机器上的不同目录中。脚本需要能够引用相对于自身的路径,因此我需要能够获取当前正在执行的文件的路径。

我知道dirname $0直接调用我的脚本时可以完美运行的习语。不幸的是,人们希望能够从完全不同的目录创建指向这些脚本的符号链接,并且仍然具有相对路径逻辑的工作。

整体目录结构示例如下:

/
 |-usr/local/lib
 |  |-foo
 |  |  |-bin
 |  |  |  |-script.sh
 |  |  |-res
 |  |  |  |-resource_file.txt
 |-home/mike/bin
 |  |-link_to_script (symlink to /usr/local/lib/foo/bin/script.sh)
Run Code Online (Sandbox Code Playgroud)

我怎样才能可靠地引用/usr/local/lib/foo/res/resource_file.txt来自script.sh它是否被调用/usr/local/lib/foo/bin/script.sh~mike/bin/link_to_script

bash shell-script symlink

69
推荐指数
3
解决办法
5万
查看次数

在这个 Dockerfile 入口点中,“set --”有什么作用?

我试图了解这个Docker 入口点的作用

在我看来,这是编写 Dockerfile 时非常常见的模式,但我的 bash 技能有限,而且我不知道所有特殊的 bash 符号功夫。

此外,很难用谷歌搜索“--”、“$!” 等等。这些在 bash 世界中被称为什么?

总而言之,下面的行试图做什么?

if [ "${1#-}" != "$1" ]; then
  set -- haproxy "$@"
fi
Run Code Online (Sandbox Code Playgroud)

shell-script set

68
推荐指数
1
解决办法
4万
查看次数

确定文件是硬链接还是符号链接?

我正在创建一个 shell 脚本,它将获取文件的文件名/路径并确定该文件是符号链接还是硬链接。

唯一的问题是,我不知道如何查看它们是否是硬链接。我创建了 2 个文件,一个是硬链接,一个是符号链接,用作测试文件。但是我如何确定一个文件是一个硬链接还是一个 shell 脚本中的符号?

另外,我如何找到符号链接的目标分区?因此,假设我有一个链接到不同分区的文件,我如何找到该原始文件的路径?

hard-link shell-script symlink files

66
推荐指数
5
解决办法
9万
查看次数

在 bash 脚本中,declare 和普通变量有什么不同?

在 bash 脚本中:

我们通过命名来创建变量:

abc=ok
Run Code Online (Sandbox Code Playgroud)

或者我们可以使用 declare

declare abc=ok
Run Code Online (Sandbox Code Playgroud)

有什么不同?

为什么 bash 有这么多方法来创建变量?

bash shell-script variable

65
推荐指数
2
解决办法
6万
查看次数