Bash 스크립트에서 매개변수 "AS IS"를 얻는 방법은 무엇입니까?

Bash 스크립트에서 매개변수 "AS IS"를 얻는 방법은 무엇입니까?

readvar.sh라는 스크립트가 있습니다.

#! /bin/bash
a="$1"

echo "$a"

매개변수를 얻고 싶습니다.문자 그대로사용자가 입력하면,

예를 들어, 사용자가 다음을 실행하는 경우:./readvar.sh \\

\\매개변수 주위에 따옴표 없이 출력되어야 합니다 .

그게 가능합니까?

답변1

일반적으로 말하면 이렇게 할 수 없습니다.

run 인 경우 ./readvar.sh \\명령이 작성된 쉘은 명령줄을 구문 분석하여 공백을 단어 구분 기호로 인식하고 백슬래시를 다음 문자(다른 백슬래시)를 인용하는 것으로 인식합니다. 그런 다음 ./readvar.sh두 단어로 끝나고 \프로그램을 시작하여 ./readvar.sh해당 두 단어를 프로세스를 시작하는 매개변수 목록에 넣습니다. (명령어 이름은 argv[0]C 프로그램에 나오는 매개변수 #0 입니다.)

./readvar.sh '\'사용자가 Perl 프로그램과 같은 것을 사용하여 스크립트를 입력하거나 시작하면 유사한 bs='\'; ./readvar "$var"결과를 얻을 수 있습니다 . system("./readvar.sh", "\\");스크립트에는 일반적으로 무슨 일이 일어나고 있는지 알 수 있는 방법이 없습니다.


당신이 할 수 있는 일은 쉘 입력에 적합한 형식으로 모든 인수를 인쇄하는 것입니다. 예를 들어 Bash에서는 다음을 사용합니다.

if [ "$#" -ne 0 ]; then
    printf "%q " "$@"
fi
echo 

출력은 Bash에서 작동하지만 $'\n'개행 등의 형태로 따옴표를 사용하기 때문에 표준 셸에서는 작동하지 않을 수 있습니다. 또한 스크립트를 \\사용하거나 시작할 때마다 출력됩니다 .\\'\'"\\"

Bash에서도 이를 남용할 수 있습니다 extdebug. 이는 실행 중인 명령의 컨텍스트에 Bash의 DEBUG 트랩에서 볼 수 있는 명령줄을 배치합니다.

export CMDLINE
trap 'CMDLINE=$BASH_COMMAND; true' DEBUG
shopt -s extdebug

하지만 거기에 있는 명령줄은 확장되지 않으므로 를 실행하면 대신 확장된 값이 env abc=$var |grep CMD표시됩니다 .env abc=$var

물론 추가 단계를 수행하는 Bash 셸에서 명령이 실행되지 않으면 작동하지 않습니다. 프로세스 트리의 상위에 이러한 셸이 있는 경우 CMDLINE이전 명령을 실행하는 명령으로 설정할 수 있습니다.


이제 이러한 까다로운 해결 방법이 존재하지만 스크립트 사용자가 스크립트가 궁극적으로 수행해야 하는 작업을 달성하기 위해 다른 방법을 사용하는 것이 더 좋고 덜 놀라운 것일 수 있습니다.

답변2

read플래그를 사용하여 호출 할 수 있습니다 -r.

-r  Backslash does not act as an
    escape character.  The backslash
    is considered to be part of the line.
    In particular, a backslash-newline pair
    may not then be used as a line
    continuation.

그래서:

IFS="" read -r a
echo "$a"

"\"를 입력하면 "\"가 에코됩니다. 또한 공백을 보존합니다(목표가 아닌 경우 IFS 비트를 제거할 수 있음).

매개변수로 전달하려면 작은따옴표를 사용하여 값을 변경하지 않고 그대로 두어야 합니다.

./readvar.sh '\\'

var.sh 읽기:

#!/bin/bash

IFS="" read -r a
./usevar.sh "$a"

var.sh를 사용하세요.

#!/bin/bash

echo "$1"

를 입력 \\하면 에코 readvar.sh됩니다 .usevar.sh\\

텍스트의 선행 및 후행 공백을 유지하려면 IFS가 필요합니다.

관련 정보