从shell脚本可移植地设置环境变量

多雷米

我具有要修改的shell脚本,以确保它在Bash环境中正确运行。

这是脚本:

#!/bin/zsh

# Some constants. The first two will become env variables.
UPDATE_DNS_API_HOST="https://example.com"
UPDATE_DNS_API_URL="$UPDATE_DNS_API_HOST/my_end_point"
CURRENT_PUBLIC_IP=$(curl -s "$UPDATE_DNS_API_URL" | grep -o '".*"' | tr -d '"')

if [[ $PUBLIC_IP == $CURRENT_PUBLIC_IP ]]; then
  echo "Current IP: "$CURRENT_PUBLIC_IP" already set."
else
  response=$(curl -s -H "Content-Type: application/json" \
             --data "$CURRENT_PUBLIC_IP" "$UPDATE_DNS_API_URL")
  echo $response
  export PUBLIC_IP="$CURRENT_PUBLIC_IP"
fi

这是我的问题:

  • 我应该将第一行更改为 #!/bin/bash
  • 尚不清楚变量何时需要引号,何时不需要引号,尤其是在条件语句中。您能在这里指出我一些资源吗?
  • 我已经看到了有关单括号和双括号的条件变化。我应该使用哪一个?
  • 运行脚本后,似乎未设置$ PUBLIC_IP。我应该设置env变量吗?

欢迎其他任何反馈。

查尔斯·达菲

一个相关的事情要记住这里是UNIX进程可以修改环境变量为自己和未来的孩子,他们开始-不是他们的父母,而没有父进程的直接参与。


如果您打算在封闭的外壳程序中设置变量,那么一种比较常见的方法是在stdout上发出外壳程序命令。这意味着任何shell命令都应移至stderr(无论如何,这都是适当的做法,因为stderr被指定为适用于信息文本和状态内容)。

与相对/bin/sh此版本确实需要bash,但用于printf '%q'确保它能够以eval-safe的方式生成变量名,所有ksh派生词(ksh,bash,zsh)都应能够读取。

#!/bin/bash
# note that while this runs with bash, ksh and zsh will also be able to eval its output
# ...POSIX sh too, when there aren't nonprintable characters causing $''-style quoting
# ...to be used.

# usage: emit_cmd varname ...
#
# emit code that defines a variable when evaluated on stdout
emit_cmd() {
  for varname; do
    printf 'export %q=%q; ' "$varname" "${!varname}"
  done
}

# Some constants. The first two will become env variables.
UPDATE_DNS_API_HOST="https://example.com"
UPDATE_DNS_API_URL="$UPDATE_DNS_API_HOST/my_end_point"

# print definitions of those variables to stdout
emit_cmd UPDATE_DNS_API_HOST UPDATE_DNS_API_URL

CURRENT_PUBLIC_IP=$(curl -s "$UPDATE_DNS_API_URL" | grep -o '".*"' | tr -d '"')

if [[ $PUBLIC_IP = $CURRENT_PUBLIC_IP ]]; then
  echo "Current IP: $CURRENT_PUBLIC_IP already set." >&2
else
  response=$(curl -s -H "Content-Type: application/json" \
             --data "$CURRENT_PUBLIC_IP" "$UPDATE_DNS_API_URL")
  echo "$response" >&2
  PUBLIC_IP="$CURRENT_PUBLIC_IP" emit_cmd PUBLIC_IP
fi

如果此脚本以名称保存ip-lookup,则可以使用以下命令将其定义的变量导入到当前shell中:

eval "$(ip-lookup)"

使用此约定可以保持与现有UNIX工具(例如ssh-agent需要修改环境变量的工具)的兼容性


请注意,我保留了有关变量名称的现有约定,但是如果有机会,您应该切换到小写名称以符合相关的POSIX约定

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章