[英]Shell: Indirect expansion throws bad substitution I'm Windows but not Mac
[英]sudo, Bad substitution, indirect parameter expansion
這是一個嘗試執行'ifndef'(ifndef.sh)的腳本:
#!/bin/bash
################# __ifndef__ #################
MAIN_SCRIPT=$(cd "$(dirname "$0")" && pwd -P)"/$(basename $0)"
script_path=$(echo $MAIN_SCRIPT | sed -e "s@/@_@g" -e "s@\.@_@g" -e "s@-@_@")
define_var="ALREADY_SOURCED_$script_path"
echo "Main_script: $MAIN_SCRIPT"
echo "script_path: $script_path"
echo "define_var: $define_var"
echo "??: ${!define_var}"
[[ ! -z ${!define_var} ]] && return
export ALREADY_SOURCED_$script_path="defined"
################# __ifndef__ #################
當我嘗試在另一個文件( main.sh
)中執行此代碼時:
. ./ifndef.sh
echo "TEST !"
使用sudo,我總是會收到此錯誤:
./main.sh: 10: ./ifndef.sh: Bad substitution
我用來啟動腳本的命令是: ./main.sh
我不知道為什么${!define_var}
有問題。
您不能使用sh
運行bash腳本-只能使用bash運行它。 特別是,您在這里使用的幾個功能(包括間接擴展la ${!foo}
和擴展測試操作符[[ ]]
)都不是POSIX sh標准的一部分,因此不能保證與sh
運行時可用。
不要運行sh yourscript
,而是運行bash yourscript
或僅運行./yourscript
(設置了shebang並授予執行權限); 和而不是用啟動它#!/bin/sh
,啟動它#!/bin/bash
。 如果源於此,請確保您從中進行采購的腳本本身以bash開始。
這里的另一件事是您的轉義還不夠完整,無法確保您的$script_path
實際上是一個有效的shell變量名稱。 無需嘗試解決此問題,只需切換到使用關聯數組-這樣鍵就可以包含NUL以外的任何字符,而這在UNIX路徑中無論如何都是無效的:
#!/usr/bin/env bash
# uses the first bash interpreter on the PATH, so on MacOS X, can use MacPorts bash
# if sourcing this, be sure to do the same in the script you're sourcing it from.
### start version check
[ -n "$BASH_VERSION" ] || {
echo "Current shell is not bash; must use bash 4.0 or later" >&2
return 1 || exit 1
}
[[ $BASH_VERSION =~ ^([4-9][.]|[0-9][0-9]+) ]] || {
echo "Bash version 4 or newer is required (using $BASH_VERSION)" >&2
return 1 || exit 1
}
### end version check
### start redefinition check
declare -A already_sourced
[[ ${already_sourced[$BASH_SOURCE]} ]] && return
already_sourced[$BASH_SOURCE]=1
### end redefinition check
以上要求使用Bash 4.x,它不是MacOS附帶的,但可以通過MacPorts獲得 。
使用BASH,您可以跳過所有sed
執行BASH本身中的所有替換操作:
#!/bin/bash
################# __ifndef__ #################
MAIN_SCRIPT=$(cd "$(dirname "$0")" && pwd -P)"/$(basename $0)"
script_path="${MAIN_SCRIPT//[\/.-]/_}"
echo "Main_script: $MAIN_SCRIPT"
echo "script_path: $script_path"
define_var="ALREADY_SOURCED_$script_path"
echo "define_var: $define_var"
echo "??: ${!define_var}"
[[ ! -z ${!define_var} ]] && return
declare -x $define_var="defined"
echo "##: ${!define_var}"
################# __ifndef__ #################
我的錯 !
我只需要在內部腳本(此處為main.sh)中添加“#!/ bin / bash”
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.