2016-12-15 2 views
0

/home/deploy/backup-scripts/utils.sh: line 41: $2: unbound variablebash ungebundene Variable bei der Verwendung von Quelle

Das kann ich nicht herausfinden, aus der Bitbucket Skripte Backups ... jemand helfen kann?

Wenn ich dies verwende, ruft ein anderes Skript es mit source. Ich kann nicht herausfinden, warum die Variable ungebunden ist, wenn ich sie mit source von einem anderen maßgeschneiderten Skript, das ich erstellte, anbringe, und es funktioniert gut, wenn sie von Bitbuckets eigenen Skripten aufgerufen wird. Gibt es ein Bash-Problem, bei dem Sie source nicht aus einem übergeordneten Skript und dann wieder aus einem untergeordneten Skript verwenden können?

# ------------------------------------------------------------------------------------- 
# 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 "$1" &> /dev/null || bail "Unable to find $1, 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="$1" 
    local conf_error_message="$2" 
    local conf_bail_message="$3" 

    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="$1" 
    local set_error_message="$2" 
    local set_bail_message="$3" 

    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 "[email protected]" 
} 

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 "[email protected]"; 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 
    "[email protected]" 
} 

# 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 
# 
# $1: string: message 
# $2: string: color (yellow/green/red/purple/gray/random) 
# $3: 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 "$1" ]; then 
     print "ERROR: HipChat notification message is missing." 
     return 1 
    fi 

    local hc_color="gray" 
    if [ -n "$2" ]; then 
     hc_color=$2 
    fi 
    local hc_notify="false" 
    if [ "1" = "$3" ]; then 
     hc_notify="true" 
    fi 

    local hc_message=$(echo "$1" | 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 
} 
+1

Was ist Ihre genaue Quelle? Ihr Fehler weist darauf hin, dass Sie dem Skript kein zweites Argument gegeben haben (http://stackoverflow.com/questions/29258603/what-do-0-1-2-mean-in-shell-script). –

+0

'SCRIPT_DIR = $ (dirname" $ ​​0 ")' 'source" $ {SCRIPT_DIR} /utils.sh "' 'source" $ {SCRIPT_DIR} /common.sh "' – eekfonky

+0

@eekfonky: müssen Sie nur vermeiden den Fehler zu bekommen (oder) zu debuggen, warum eine Variable, die einen Wert haben soll, tatsächlich leer ist? – Inian

Antwort

1

$2 ist die zweite positional parameter oder Argument, wenn man so will, des Skripts. Sie müssen diesen Parameter angeben, wenn Sie eine Datei wie bei jedem anderen Aufruf eines Skripts, das einen zweiten Parameter erwartet, "sourcen".

In Ihrem Fall scheint das Skript drei Parameter zu erwarten, so nennt es als:

source /path/to/the/script my_var_name my_err_msg my_bail_msg 

Zum Beispiel:

$ cat test.sh 
#!/usr/bin/env bash 

source test2.sh singing rain 
$ cat test2.sh 
#!/usr/bin/env bash 

var1="$1" 
var2="$2" 

printf "I'm %s in the %s\n" $var1 $var2 
$ ./test.sh 
I'm singing in the rain 

Wenn Sie vergessen, die Argumente zu spezifizieren (und wenn Sie verwenden set -u) erhalten Sie eine Fehlermeldung erhalten:

$ cat test.sh 
#!/usr/bin/env bash 

set -u 

source test2.sh 
$ cat test2.sh 
#!/usr/bin/env bash 

var1="$1" 
var2="$2" 

printf "I'm %s in the %s\n" $var1 $var2 
$ ./test.sh 
test2.sh: line 3: $1: unbound variable 
+0

Denken Sie daran, "nomenset" zu entfernen, dies umgeht einfach den Fehler, den der OP sieht. Nicht sicher, ob er das will oder warum das Skript auf eine nicht initialisierte Variable verweist. – Inian

+0

@einverstanden. Ich rate absolut nicht, 'set -o nounset' (äquivalent zu' set -u') zu entfernen. Im Gegenteil, dies sollte immer eingestellt werden. –

0

Es scheint, wenn ichverwenden 10 anstatt source funktioniert es?

+0

'exec' wird nicht den Kontext Ihres Skripts verwenden, um den aufgerufenen Kontext auszuführen. Wenn Sie' set -u' verwenden, wird es nicht auf das Skript angewendet, das Sie aufrufen. Wenn Sie also 'exec script.sh' ausführen, wird das nicht initialisierte' $ 2' auf leer oder '' '' gesetzt, anstatt einen Fehler auszulösen. Wenn es funktioniert, ist es gut für Sie, aber das Skript, das Sie verwenden, ist eindeutig dazu gedacht, mit Parametern verwendet zu werden, damit es Sie später beißt. ;-) –

+0

Danke, es funktioniert gerade, aber ich brauche eine dauerhafte Lösung, damit ich es mit 'source' bezeichnen kann – eekfonky

Verwandte Themen