bash 使用源时bash未绑定变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41163521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
bash unbound variable when using source
提问by eekfonky
/home/deploy/backup-scripts/utils.sh: line 41: $2: unbound variable
/home/deploy/backup-scripts/utils.sh: line 41: $2: unbound variable
I cannot figure this out from the Bitbucket backups scripts...can anyone help?
我无法从 Bitbucket 备份脚本中弄清楚这一点……有人可以帮忙吗?
When I use this, another script calls it using source
. I cannot figure out why the variable is unbound when I call it with source
from another bespoke script I created and it works fine when called from Bitbuckets own scripts?. Is there a bash issue where you cannot use source
from a parent script and then again from within a child script?
当我使用它时,另一个脚本使用source
. 当我source
从我创建的另一个定制脚本调用它时,我无法弄清楚为什么该变量未绑定,并且在从 Bitbuckets 自己的脚本调用时它工作正常?。是否存在 bash 问题,您无法source
从父脚本使用,然后再从子脚本中使用?
# -------------------------------------------------------------------------------------
# Common utilities for logging, terminating script execution and Hipchat integration.
# -------------------------------------------------------------------------------------
# Terminate script execution with error message
function bail {
error "$*"
print_stack_trace
exit 99
}
# Test for the presence of the specified command and terminate script execution if not found
function check_command {
type -P "" &> /dev/null || bail "Unable to find , please install it and run this script again"
}
# Log an debug message to the console if BITBUCKET_VERBOSE_BACKUP=true
function debug {
if [ "${BITBUCKET_VERBOSE_BACKUP}" = "true" ]; then
print "$(script_ctx)[$(hostname)] DEBUG: $*"
fi
}
# Log an error message to the console and publish it to Hipchat
function error {
# Set the following to have log statements print contextual information
echo "$(script_ctx)[$(hostname)] ERROR: $*" > /dev/stderr
hc_announce "[$(hostname)] ERROR: $*" "red" 1
}
# Log an info message to the console and publish it to Hipchat
function info {
# Set the following to have log statements print contextual information
print "$(script_ctx)[$(hostname)] INFO: $*"
hc_announce "[$(hostname)] INFO: $*" "gray"
}
# Checks if a variable is zero length, if so it prints the supplied error message and bails
function check_config_var {
local conf_var_name=""
local conf_error_message=""
local conf_bail_message=""
if [ -z "${conf_error_message}" ]; then
conf_error_message="The configuration var '${conf_var_name}' is required, please update '${BACKUP_VARS_FILE}'."
fi
if [ -z "${conf_bail_message}" ]; then
conf_bail_message="See bitbucket.diy-backup.vars.sh.example for the defaults and instructions."
fi
check_var "${conf_var_name}" "${conf_error_message}" "${conf_bail_message}"
}
# Similar to check_config_var but does does not print the extra message about consulting the vars file
function check_var {
local set_var_name=""
local set_error_message=""
local set_bail_message=""
if [ -z "${!set_var_name}" ]; then
if [ -z "${set_error_message}" ]; then
set_error_message="Fatal error '${set_var_name}' has not been set"
fi
if [ -z "${set_bail_message}" ]; then
bail "${set_error_message}"
else
error "${set_error_message}"
bail "${set_bail_message}"
fi
fi
}
# A function with no side effects. Normally called when a callback does not need to do any work
function no_op {
echo > /dev/null
}
# Log a message to the console without adding standard logging markup
function print {
echo "$@"
}
function script_ctx {
if [ -n "${BASH_VERSION}" ]; then
local depth=0
for func in ${FUNCNAME[@]}; do
case "${func}" in
debug|info|error|bail|check_config_var|check_var|run|script_ctx|print_stack_trace)
depth=$((${depth}+1))
;;
esac
done
echo "[$(basename ${BASH_SOURCE[${depth}]}):${BASH_LINENO[${depth}]} -> ${FUNCNAME[${depth}]}]"
fi
}
function print_stack_trace {
if [ -n "${BASH_VERSION}" ]; then
local idx=0
local depth=" "
echo "Stack trace:" > /dev/stderr
for func in ${FUNCNAME[@]}; do
case "${func}" in
debug|info|error|bail|check_config_var|check_var|run|script_ctx|print_stack_trace)
;;
*)
echo "${depth}[${BASH_SOURCE[${idx}]}:${BASH_LINENO[${idx}]} -> ${FUNCNAME[${idx}]}]" > /dev/stderr
;;
esac
depth="${depth} "
idx=$((${idx}+1))
done
fi
}
# Log then execute the provided command
function run {
if [ "${BITBUCKET_VERBOSE_BACKUP}" = "true" ]; then
local cmdline=
for arg in "$@"; do
case "${arg}" in
*\ * | *\"*)
cmdline="${cmdline} '${arg}'"
;;
*)
cmdline="${cmdline} ${arg}"
;;
esac
done
case "${cmdline}" in
*curl*)
cmdline=$(echo "${cmdline}" | sed -e 's/-u .* /-u ******:****** /g')
;;
*PGPASSWORD=*)
cmdline=$(echo "${cmdline}" | sed -e 's/PGPASSWORD=".*" /PGPASSWORD="**********" /g')
;;
esac
debug "Running${cmdline}" > /dev/stderr
fi
"$@"
}
# Log a success message to the console and publish it to Hipchat
function success {
print "[$(hostname)] SUCC: $*"
hc_announce "[$(hostname)] SUCC: $*" "green"
}
# -------------------------------------------------------------------------------------
# Internal methods
# -------------------------------------------------------------------------------------
# Publish a message to Hipchat using the REST API
#
# : string: message
# : string: color (yellow/green/red/purple/gray/random)
# : integer: notify (0/1)
#
function hc_announce {
if [ -z "${HIPCHAT_ROOM}" ]; then
return 0
fi
if [ -z "${HIPCHAT_TOKEN}" ]; then
return 0
fi
if [ -z "" ]; then
print "ERROR: HipChat notification message is missing."
return 1
fi
local hc_color="gray"
if [ -n "" ]; then
hc_color=
fi
local hc_notify="false"
if [ "1" = "" ]; then
hc_notify="true"
fi
local hc_message=$(echo "" | sed -e 's|"|\\"|g')
local hipchat_payload="{\"message\":\"${hc_message}\",\"color\":\"${hc_color}\",\"notify\":\"${hc_notify}\"}"
local hipchat_url="${HIPCHAT_URL}/v2/room/${HIPCHAT_ROOM}/notification?auth_token=${HIPCHAT_TOKEN}"
! curl ${CURL_OPTIONS} -X POST -H "Content-Type: application/json" -d "${hipchat_payload}" "${hipchat_url}"
true
}
回答by Julien Lopez
$2
is the second positional parameter, or argument if you will, of the script. You need to specify this parameter when "sourcing" a file as you would for any other call to a script that expects a second parameter.
$2
是脚本的第二个位置参数或参数(如果您愿意的话)。您需要在“采购”文件时指定此参数,就像对需要第二个参数的脚本的任何其他调用一样。
In your case, the script seems to expect three parameters, so call it as:
在您的情况下,脚本似乎需要三个参数,因此将其称为:
source /path/to/the/script my_var_name my_err_msg my_bail_msg
For example:
例如:
$ cat test.sh
#!/usr/bin/env bash
source test2.sh singing rain
$ cat test2.sh
#!/usr/bin/env bash
var1=""
var2=""
printf "I'm %s in the %s\n" $var1 $var2
$ ./test.sh
I'm singing in the rain
If you forget to specify the arguments (and if you use set -u
) you will get an error:
如果您忘记指定参数(并且如果您使用set -u
),您将收到错误消息:
$ cat test.sh
#!/usr/bin/env bash
set -u
source test2.sh
$ cat test2.sh
#!/usr/bin/env bash
var1=""
var2=""
printf "I'm %s in the %s\n" $var1 $var2
$ ./test.sh
test2.sh: line 3: : unbound variable
回答by eekfonky
It seems if I use exec
rather than source
it works?
似乎我使用exec
而不是source
它的工作原理?