쉘 스크립트에서 명령에 공백이 포함된 인수를 전달하시겠습니까? [복사]

쉘 스크립트에서 명령에 공백이 포함된 인수를 전달하시겠습니까? [복사]

아래 편집 내용을 참조하세요. 감사합니다.

다음 테스트 스크립트가 있습니다(중요: 이 부분은 변경할 수 없습니다):

while (($#)); do
  echo $1
  shift
done

이 명령을 실행하면 ./test aaa "bbbb cccc" ddd 다음과 같은 출력이 생성됩니다.

aaa
bbbb cccc
ddd

이것은 제정신의 사람이라면 누구나 기대할 수 있는 것입니다.

다른 스크립트가 있습니다.

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""

# ----

PARAMS=""

// $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS="$PARAMS --$1 \"$2\""
    fi
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

echo ./test $PARAMS
./test $PARAMS

의 출력은 echo이므로 ./test --mode "good" --status "okay" --name "bro" --description "very good man dood"예상 출력 ./test $PARAMS은 다음과 같습니다.

--mode
good
--status
okay
--name
bro
--description
very good man dood

그러나 어떤 이유로 다음과 같은 결과가 나타납니다.

--mode
"good"
--status
"okay"
--name
"bro"
--description
"very
good
man
dood"

출력을 복사하여 echo ./test $PARAMS붙여넣으면 예상되는 출력을 얻습니다 ./test. 그래서 마지막 실행 줄을 제거 ./test하고 그 echo줄을 마지막에 유지하려고 시도했지만 $(./script)여전히 작동하지 않고 알아낼 수 없습니다.

내가 뭘 잘못했나요?


편집하다:@steeldriver의 솔루션은 작동하지만 또 다른 제한 사항이 있습니다. 사용자가 자신의 매개 변수를 보낼 수 있도록 허용해야 합니다.

따라서 다음 스크립트가 있습니다(@steeldriver 덕분에):

#!/bin/bash

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""
arguments="--config \"blablabla=yes\" --config2 \"bla2=no problem\""

# ----

declare -a PARAMS

# $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS+=("--$1" "$2")
    fi
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

# (1)
PARAMS+=("$arguments")

# (2)
PARAMS+=($arguments)

echo ./test "${PARAMS[@]}" 
./test "${PARAMS[@]}"

원하는 출력은 다음과 같습니다.

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config
blablabla=yes
--config2
bla2=no problem

그러나 내가 얻는 결과는 다음과 같습니다.

그리고 (1):

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config "blablabla=yes" --config2 "bla2=no problem"

그리고 (2):

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config
"blablabla=yes"
--config2
"bla2=no
problem"

고마워하는!

답변1

문자열 변수 대신 배열을 사용하십시오.

#!/bin/bash

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""

# ----

declare -a PARAMS

# $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS+=("--$1" "$2")
    fi
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

echo ./test "${PARAMS[@]}"
./test "${PARAMS[@]}"

시험

$ ./other.sh
./test --mode good --status okay --name bro --description very good man dood
--mode
good
--status
okay
--name
bro
--description
very good man dood

답변2

@steeldriver의 알림 덕분에 사용자 매개변수를 올바르게 추가하고 원하는 출력을 얻을 수 있었습니다. 이제 이것은 내 스크립트입니다.

#!/bin/bash

mode="good"
status="okay"
name="bro"
description="very good man dood"
extra=""
arguments="--config \"blablabla=yes\" --config2 \"bla2=no problem\""

# ----

declare -a PARAMS

# $1: key, $2: value
function addParam {
    if [ ! -z "$2" ]; then
        PARAMS+=("--$1" "$2")
    fi
}

# This function right here
function addUserArguments {
    while (($#)); do
      PARAMS+=("$1")
      shift
    done
}

addParam "mode" "$mode"
addParam "status" "$status"
addParam "name" "$name"
addParam "description" "$description"
addParam "extra" "$extra"

# And this line right here
eval addUserArguments $arguments

./test "${PARAMS[@]}"

출력은 다음과 같습니다

--mode
good
--status
okay
--name
bro
--description
very good man dood
--config
blablabla=yes
--config2
bla2=no problem

관련 정보