我正在创建一个 AWS 分销商包,以修改不同 Linux 服务器上的 syslog 配置。我编写了一些简单的 bash 脚本来处理安装、卸载和更新。我以为这会是通用的。然而,今天我发现 AWS 使用 来sh
执行脚本(即sh install.sh
),而在 Ubuntu/Debian 上,默认使用 DASH 而不是 BASH。因此我的脚本失败了:
update errors: update.sh: 3: update.sh: function: not found
update.sh: 9: update.sh: Syntax error: "}" unexpected
failed to run commands: exit status 2
Failed to install package; install status Failed
我无法更改 AWS 行为。而且我不想修改服务器上的任何配置。那么,看来我唯一的选择就是修改脚本文件本身?
第一个选择是让脚本具有通用性,这样它就可以在任何版本的 Linux 上运行。第二个选择是为 Debian 创建与 DASH 兼容的不同脚本。
不幸的是,我找不到太多关于 dash 编程的信息。有什么建议吗?
有问题的 3 个脚本是....
安装文件
#!/bin/bash
function isInstalled {
if sudo ls /etc/rsyslog.d/xdr.conf >/dev/null 2>&1; then
true
else
false
fi
}
if isInstalled; then
exit 0
else
sudo cp xdr.conf /etc/rsyslog.d/xdr.conf
sudo service rsyslog restart
fi
卸载程序
#!/bin/bash
function isInstalled {
if sudo ls /etc/rsyslog.d/xdr.conf >/dev/null 2>&1; then
true
else
false
fi
}
if isInstalled; then
sudo rm /etc/rsyslog.d/xdr.conf
sudo service rsyslog restart
else
exit 0
fi
更新脚本
#!/bin/bash
function isDiff {
if sudo diff xdr.conf /etc/rsyslog.d/xdr.conf >/dev/null 2>&1; then
false
else
true
fi
}
if isDiff; then
sudo cp xdr.conf /etc/rsyslog.d/xdr.conf
sudo service rsyslog restart
else
exit 0
fi
答案1
bash/ksh/zsh 中有两种不同的函数语法。您使用的是 ksh 样式:function name { … }
。另一种形式就是name() { … }
,它是原始 Bourne shell 中后期引入的形式。
这样做确实毫无意义:
if cmd; then
true
else
false
fi
除了将所有非零返回状态变为 1 之外,这与运行 完全相同cmd
。并且由于函数精简为仅一行,您实际上不需要函数。我还想使用cmp -s
而不是diff
或 简单地无条件地执行复制。并且不要使用ls
来测试文件是否存在。命令test
或 都[
用于此目的:[ -e /etc/rsyslog.d/xdr.conf ]
。如果您有 ,那确实以外部形式存在sudo
。