我一直在看其他人写的一些脚本(特别是 Red Hat),他们的很多变量都是使用以下符号分配的
VARIABLE1="${VARIABLE1:-some_val}"
或一些扩展其他变量
VARIABLE2="${VARIABLE2:-`echo $VARIABLE1`}"
使用这种表示法而不是直接声明值有什么意义(例如, VARIABLE1=some_val)有什么意义?
这种表示法是否有好处或可以防止可能出现的错误?
是否:-有特定的含义在这方面?
以下 bash 语法验证是否param不为空:
[[ ! -z $param ]]
Run Code Online (Sandbox Code Playgroud)
例如:
param=""
[[ ! -z $param ]] && echo "I am not zero"
Run Code Online (Sandbox Code Playgroud)
没有输出,很好。
但是当param除了一个(或多个)空格字符为空时,情况就不同了:
param=" " # one space
[[ ! -z $param ]] && echo "I am not zero"
Run Code Online (Sandbox Code Playgroud)
“我不是零”是输出。
如何更改测试以将仅包含空格字符的变量视为空?
所以我喜欢尽可能地强化我的 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 将反引号内的非零返回码视为足以退出的理由?
我想确保在脚本的某个点,在source配置文件之后,设置了几个变量,如果没有,则停止执行,告诉用户丢失的变量。我试过了
for var in $one $two $three ; do
...
Run Code Online (Sandbox Code Playgroud)
但是如果例如$two未设置,则永远不会为 执行循环$two。我尝试的下一件事是
for var in one two three ; do
if [ -n ${!var} ] ; then
echo "$var is set to ${!var}"
else
echo "$var is not set"
fi
done
Run Code Online (Sandbox Code Playgroud)
但是如果没有设置两个,我仍然会得到“两个设置为”而不是“两个未设置”。
如何确保设置了所有必需的变量?
更新/解决方案:我知道“设置”和“设置,但为空”之间存在差异。我现在使用(感谢/sf/answers/1172747551/和这个问题的答案)以下内容:
if [ -n "${!var:-}" ] ; then
Run Code Online (Sandbox Code Playgroud)
所以,如果var设置了但为空,它仍然被认为是无效的。
在 python 中,我们可以使用自动应用和针对函数执行的代码来装饰函数。
bash 中是否有类似的功能?
在我目前正在处理的脚本中,我有一些样板文件来测试所需的参数并在它们不存在时退出 - 如果指定了调试标志,则显示一些消息。
不幸的是,我必须将这段代码重新插入到每个函数中,如果我想更改它,我将不得不修改每个函数。
有没有办法从每个函数中删除此代码并将其应用于所有函数,类似于 python 中的装饰器?
我在脚本中看到过这样的结构:
if somevar="$(somecommand 2>/dev/null)"; then
...
fi
Run Code Online (Sandbox Code Playgroud)
这是在某处记录的吗?变量的返回状态是如何确定的,它与命令替换有什么关系?(例如,我会得到相同的结果if echo "$(somecommand 2>/dev/null)"; then吗?)
我正在编写一个广泛使用 wget 的 bash 脚本。为了在一个地方定义所有通用参数,我将它们存储在变量中。这是一段代码:
useragent='--user-agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"'
cookies_file="/tmp/wget-cookies.txt"
save_cookies_cmd="--save-cookies $cookies_file --keep-session-cookies"
load_cookies_cmd="--load-cookies $cookies_file --keep-session-cookies"
function mywget {
log "#!!!!!!!!!# WGET #!!!!!!!!!# wget $quiet $useragent $load_cookies_cmd $@"
wget $useragent $load_cookies_cmd "$@"
}
Run Code Online (Sandbox Code Playgroud)
可悲的是不起作用。不知何故,我缺少将参数存储在变量 $useragent、$save_cookies_cmd、$load_cookies_cmd 和 caling wget 将这些变量作为参数传递的正确方法。
我想要这样的结果命令行:
wget --user-agent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0" --load-cookies /tmp/wget-cookies.txt --keep-session-cookies http://mysite.local/myfile.php
Run Code Online (Sandbox Code Playgroud)
编辑:我的最终解决方案:
最后,我的脚本正确地使用了这个:
useragent="Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
useragent_cmd="--user-agent=$useragent"
cookies_file="/tmp/wget-cookies.txt"
save_cookies_cmd="--save-cookies $cookies_file --keep-session-cookies"
load_cookies_cmd="--load-cookies $cookies_file --keep-session-cookies"
function mywget {
log …Run Code Online (Sandbox Code Playgroud) 我正在编写一个 bash 脚本,随着我的学习,我了解了陷阱、信号、函数返回代码和其他我以前没有使用过的功能。
我可能正在错误地思考事情 - 我正在寻找一些建议。
我正在设置以下选项:
set -o errexit
set -o nounset
set -o noclobber
Run Code Online (Sandbox Code Playgroud)
我的 bash 脚本中有以下退出和错误陷阱:
# Error handler. This function is called anytime an ERR signal is received.
# This function should never be explictly called.
function _trap_error () {
if [ ! -v _VERBOSE ]; then
echo "An error has occurred. Exiting."
else
_name="$0" # name of the script
_lastline="$1" # argument 1: last line of error occurence
_lasterr="$2" # argument 2: error code of …Run Code Online (Sandbox Code Playgroud) “冒号”和“美元问号”可以组合起来检查脚本是否sh有参数并将其直接分配给感兴趣的变量:
cmd=${1:? "Usage: $0 {build|upload|log}"}
Run Code Online (Sandbox Code Playgroud)
有人可以一步步解释它是如何工作的,以及我在哪里可以找到其实现的详细信息吗?例如,我希望能够调用函数而不是打印到stderr.
help() {
echo $"Usage: $0 {build|upload|log}"
exit 1
}
cmd=${1:? help}
Run Code Online (Sandbox Code Playgroud)
为什么这是不可能的?
我想要一个 Unix 脚本,它将从用户那里获取多个列号并反转内容。
declare -a param="$@"
# enter 0 when exit the insert element
echo "Enter the numbers"
read n
while [ $n -ne 0 ]
do
x[$i]=`expr $n`
read n
let i++
done
#display the all array elements
echo "Array values ${x[@]}"
echo "Array values ${x[*]}"
# To find the array length
length=${#x[*]}
echo $length
Run Code Online (Sandbox Code Playgroud)