这是一个尝试做“ifndef' (ifndef.sh):
if
当我尝试在另一个文件(#!/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
使用sudo,我总是会收到此错误:
. ./ifndef.sh
echo "TEST !"
我用来启动脚本的命令是:./main.sh: 10: ./ifndef.sh: Bad substitution
我不知道为什么./main.sh
有问题。
答案 0 :(得分:2)
您无法使用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获得。
答案 1 :(得分:1)
使用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__ #################
答案 2 :(得分:0)
我的坏!
我只需添加'#!/ bin / bash'在内部脚本(main.sh here)