$PATH
다음과 같이 설정할 수 있는 bash 기능이 있습니다 .
assign-path()
{
str=$1
# if the $PATH is empty, assign it directly.
if [ -z $PATH ]; then
PATH=$str;
# if the $PATH does not contain the substring, append it with ':'.
elif [[ $PATH != *$str* ]]; then
PATH=$PATH:$str;
fi
}
하지만 문제는 다른 변수에 대해 다른 함수를 작성해야 한다는 것입니다(예: $CLASSPATH
유사한 함수에 대해 다른 함수를 작성하는 assign-classpath()
등). 참조로 액세스할 수 있도록 bash 함수에 매개 변수를 전달하는 방법을 찾을 수 없습니다.
비슷한 게 있으면 더 좋을 것 같아요 -
assign( bigstr, substr )
{
if [ -z bigstr ]; then
bigstr=substr;
elif [[ bigstr != *str* ]]; then
bigstr=bigstr:substr;
fi
}
bash에서 위와 같은 것을 구현하는 방법을 아시나요?
답변1
bash
이를 사용하여 ${!varname}
다른 변수가 참조하는 내용을 확장 할 수 있습니다. 예를 들어:
$ var=hello
$ foo () { echo "${!1}"; }
$ foo var
hello
매뉴얼 페이지에서:
${!prefix*}
${!prefix@}
Names matching prefix. Expands to the names of variables whose names
begin with prefix, separated by the first character of the IFS special
variable. When @ is used and the expansion appears within double quotes,
each variable name expands to a separate word.
또는 참조된 변수의 내용을 설정하려면(위험 없음 eval
) 을 사용할 수 있습니다 declare
. 예를 들어:
$ var=target
$ declare "$var=hello"
$ echo "$target"
hello
따라서 다음과 같은 함수를 작성할 수 있습니다( declare
함수 내에서 사용하는 경우 함수를 제공해야 하므로 주의하세요 -g
. 그렇지 않으면 변수가 로컬이 됩니다).
shopt -s extglob
assign()
{
target=$1
bigstr=${!1}
substr=$2
if [ -z "$bigstr" ]; then
declare -g -- "$target=$substr"
elif [[ $bigstr != @(|*:)$substr@(|:*) ]]; then
declare -g -- "$target=$bigstr:$substr"
fi
}
다음과 같이 사용하세요.
assign PATH /path/to/binaries
substr
if 가 이미 콜론으로 구분된 멤버 중 하나의 하위 문자열 bigstr
이지만 자체 멤버가 아닌 경우 추가되지 않는 버그도 수정했습니다 . 예를 들어, 이미 포함된 /bin
에 추가할 수 있습니다 . 이는 문자열이나 콜론의 시작/끝 및 기타 항목을 일치시키기 위해 세트를 사용합니다. 그렇지 않은 경우 대안은 다음과 같습니다.PATH
/usr/bin
extglob
extglob
[[ $bigstr != $substr && $bigstr != *:$substr &&
$bigstr != $substr:* && $bigstr != *:$substr:* ]]
답변2
Bash 4.3의 새로운 기능은 & -n
옵션입니다.declare
local
func() {
local -n ref="$1"
ref="hello, world"
}
var='goodbye world'
func var
echo "$var"
출력되는 것은 입니다 hello, world
.
답변3
매개변수를 설정하는 데 사용할 수 있습니다 eval
. 이 명령에 대한 지침은 다음에서 찾을 수 있습니다.여기. 다음 사용법은 eval
올바르지 않습니다.
잘못된(){ 평가$1=$2 }
추가 평가에 대해서는 eval
다음을 사용해야 합니다.
분배하다(){ 평가$1='$2' }
다음 기능을 사용한 결과를 확인하십시오.
$X1='$X2' $X2='$X3' $X3='xxx' $ $에코:$X1: :$X2: $에코:$X2: :$X3: $에코:$X3: :트리플 엑스: $ $ 오류Y $X1 $에코:$Y: :$X3: $ $ 할당 Y $X1 $에코:$Y: :$X2: $ $ Y "hello world" 할당 $에코:$Y: :안녕하세요 세계: $#다음 내용은 예상치 못한 내용일 수 있습니다. $ 할당Z $Y $echo ":$Z:" :안녕하세요: $ # 따라서 두 번째 매개변수가 변수인 경우 따옴표로 묶어야 합니다. $ 할당Z "$Y" $echo ":$Z:" :안녕하세요 세계:
하지만 그것을 사용하지 않고도 목표를 달성할 수 있습니다 eval
. 나는 이 간단한 방법을 선호한다.
다음 함수는 올바른 방식으로 대체를 수행합니다. (희망합니다)
증가하다(){ 지역 전류=$1 로컬 증분=$2 지역의 새로운 if [[ -z $CURRENT ]]; 새로운=$향상됨 엘리프[[! ( ( $CURRENT = $AUGMENT ) || ( $CURRENT = $AUGMENT:* ) || \ ( $current = *:$AUGMENT ) || ( $current = *:$AUGMENT:* ) ) ]];그러면 신규=$현재:$향상됨 기타 새로운=$현재 필리핀 제도 에코 "$새" }
다음 출력을 확인하십시오.
확장 /usr/bin /bin /usr/bin:/bin 확장 /usr/bin:/bin /bin /usr/bin:/bin 확장 /usr/bin:/bin:/usr/local/bin /bin /usr/bin:/bin:/usr/local/bin /bin:/usr/bin /bin 강화 /bin:/usr/bin /bin /bin 강화 /쓰레기통 /usr/bin 확장: /bin /usr/bin::/bin 확장 /usr/bin:/bin: /bin /usr/bin:/bin: /usr/bin:/bin:/usr/local/bin:/bin을 확장합니다. /usr/bin:/bin:/usr/local/bin: /bin:/usr/bin: /bin 강화 /bin:/usr/bin: /bin 강화: /bin /쓰레기통: 향상:/bin ::/쓰레기통 "/usr lib" "/usr bin"을 확장합니다. /usrlib:/usrbin "/usr lib:/usr bin" "/usr bin"을 확장합니다. /usrlib:/usrbin
이제 augment
이 함수를 사용하여 다음과 같은 방법으로 변수를 설정할 수 있습니다.
PATH=`PATH /bin 확장` CLASSPATH=`CLASSPATH /bin 추가` LD_LIBRARY_PATH=`확장 LD_LIBRARY_PATH /usr/lib`
답변4
assign ()
{
if [ -z ${!1} ]; then
eval $1=$2
else
if [[ ${!1} != *$2* ]]; then
eval $1=${!1}:$2
fi
fi
}
$ echo =$x=
==
$ assign x y
$ echo =$x=
=y=
$ assign x y
$ echo =$x=
=y=
$ assign x z
$ echo =$x=
=y:z=
이것이 적절한가?