eve*_*ner 6 command-line bash scripts
我有一个使用 shebang : 的脚本#!/bin/sh,但是当我在 Ubuntu 14.04 终端中运行它时,它不起作用,并且它说某些行具有意外的运算符。
我在 MacOSX 中的朋友可以使用#!/bin/shshebang运行该脚本。
我试图将 shebang 更改为#!/usr/bin/env bash,突然间,脚本起作用了!这里究竟发生了什么?
我真的希望我也可以运行!#/bin/shshebang,这样我就不需要更改我拥有的每个脚本。
mur*_*uru 25
您在另一台计算机上的朋友可能使用的操作系统已/bin/sh链接到/bin/bash. 在 Ubuntu(实际上是 Debian 和大多数 Debian 衍生版)中,/bin/sh不是链接到/bin/bash,而是链接到/bin/dash,它不支持许多bash特定的功能,但速度要快得多。
在 Arch Linux 上:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Sep 28 15:26 /bin/sh -> bash
Run Code Online (Sandbox Code Playgroud)
在 Ubuntu 上:
$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 19 2014 /bin/sh -> dash
Run Code Online (Sandbox Code Playgroud)
如果您使用shebang,请认真对待。由于您的脚本包含bash-isms,请/bin/bash在 shebang 中使用。或者编写可移植的、符合 POSIX 的代码。
您可以使用这篇 LWN 文章中checkbashisms提到的程序来加快此过程。它是包的一部分,所以先安装它:devscripts
sudo apt-get install devscripts
Run Code Online (Sandbox Code Playgroud)
因此:
checkbashisms /path/to/script.sh || sed -i '1 s;/bin/sh;/bin/bash;' /path/to/script.sh
Run Code Online (Sandbox Code Playgroud)
您可以将其转换为脚本(例如convert.sh):
#! /bin/sh
for i
do
checkbashisms "$i"
if [ $? = "1" ]
then
sed -i '1 s;/bin/sh;/bin/bash;' "$i"
fi
done
Run Code Online (Sandbox Code Playgroud)
的具体返回码1意味着checkbashisms发现了一个可能的bashism,其他返回值表示其他问题(文件不可读、缺少shebang等),因此我们可以检查该特定返回值。
然后调用它:
./convert.sh /path/to/first/script.sh /path/to/second/script.sh
# or
./convert.sh *.sh
# or
find . -iname '*.sh' -exec ./convert.sh {} +
Run Code Online (Sandbox Code Playgroud)
替换/bin/sh为指向/bin/bash.
推荐阅读:
bash和dash语法并显示所需的更改。/bin/sh- 类似。