공백이 포함된 경로를 인수로 전달

공백이 포함된 경로를 인수로 전달

공백이 포함된 일부 문자열 변수를 매개변수로 프로그램에 전달하는 데 어려움이 있습니다.
전달되는 인수를 디버깅하고 표시하기 위해 데모 Python 스크립트를 만들었습니다.

##### show_args.py #####

import sys

def main():
    # Display the arguments passed to the script
    print "Number of arguments =", len(sys.argv)
    for arg in sys.argv:
        print arg

if __name__ == '__main__':
    main()

이제 문제를 보여주는 스크립트는 다음과 같습니다.

path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc $path_with_spaces/xyz"

python show_args.py $arg_list

출력 -:

Number of arguments = 5
show_args.py
/home/anmol/blah
blah/abc
/home/anmol/blah
blah/xyz

내가 정말로 원하는 것은 이것이다 -:

path_with_spaces="$HOME/blah blah"

python show_args.py "$path_with_spaces/abc" "$path_with_spaces/xyz"

출력 -:

Number of arguments = 3
show_args.py
/home/anmol/blah blah/abc
/home/anmol/blah blah/xyz

공백이 있는 경로에서만 문제가 발생하는지 확인하기 위해 다음 스크립트를 만들었습니다.

path_without_spaces="$HOME/blah"
arg_list="$path_without_spaces/abc $path_without_spaces/xyz"

python show_args.py $arg_list

출력 -:

Number of arguments = 3
show_args.py
/home/anmol/blah/abc
/home/anmol/blah/xyz

이 문제에 대한 해결책을 찾다가 우연히 발견했습니다.이 답변, 이 방법에 따르면 올바른 방법은 매개 변수를 문자열 변수 대신 배열 변수에 넣는 것입니다.
이 새로운 접근 방식을 보여주는 스크립트 -:

path_with_spaces="$HOME/blah blah"
arg_list=("$path_with_spaces/abc" "$path_with_spaces/xyz")

python show_args.py "${arg_list[@]}"

출력 -:

Number of arguments = 3
show_args.py
/home/anmol/blah blah/abc
/home/anmol/blah blah/xyz

이 솔루션은 제대로 작동하지만배열 변수 대신 문자열 변수를 사용하여 동일한 작업을 수행할 수 있는 방법이 있는지 여전히 궁금합니다.

내 시스템 구성 -:

  • 우분투 14.04 LTS
  • 헤비스트라이크 4.3.11
  • 그놈 터미널 3.6.2

답변1

존재하다:

path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc $path_with_spaces/xyz"

python show_args.py $arg_list

스칼라/문자열 변수를 사용하고 있으며분할+전역연산자(변수를 인용 해제)는 변수의 내용을 분할하고 에 전달할 인수를 생성합니다 python.

이것나뉘다~의 일부분할+전역연산자는 특수 인수에 저장된 문자를 분할합니다 $IFS.

여기에서 비활성화할 수 있습니다전반적인 상황경로에서 찾을 수 없는 문자를 분할하고 분할합니다. 예를 들어,새로운 팀다음 경로에서 찾을 수 없습니다:

path_with_spaces="$HOME/blah blah"
arg_list="$path_with_spaces/abc
$path_with_spaces/xyz"
IFS="
"
set -f # disable glob.
python show_args.py $arg_list

eval또한 쉘 인용을 사용하고 쉘이 이러한 인용을 해석 하도록 할 수도 있습니다 ( bash여기서는 특정 기능이 사용됩니다):

printf -v arg_list '%q ' "$path_with_spaces/abc" \
                         "$path_with_spaces/xyz"

eval "python show_args.py $arg_list"

답변2

예.

기본 경로 구분 기호를 사용하여 경로를 구분할 수 있습니다. 경로 이름에 두 개의 잘못된 문자가 있습니다:

  • \0NUL성격

  • 경로 /구분 기호

공교롭게도 쉘의 경로명을 구분할 수 있습니다.내부 필드 구분 기호 $IFS특수 매개변수. 두 개 이상의 구분 기호가 차례로 나타나면 결과 구성 요소는 \0NUL경로 이름이 될 수 없는 값 인수가 됩니다.

작동하려면 모든 경로를 직접 루팅해야 합니다.(따라서 루트 제외 //), 표준 경로가 있는지 확인해야 합니다. 그렇지 않으면 최소한 모든 경로가 //*각 경로에 한 번 나타나도록 압축됩니다.(포인트는 아프지 않습니다 - 또는 도움이 됩니다). 일단 이렇게 하면:


paths='/path/one//path/t w o//p a t h/t h r e e/'
set -f --; IFS=/
for p in ${paths#/}$IFS
do  printf ${p:+/}%s\\n "$*"
    set -- ${p:+"$@"/$p}
done

/path/one
/path/t w o
/p a t h/t h r e e

$PWD를 사용하여 정식 경로를 얻을 수 있습니다 cd.


cd -- /some//../screwy/../path/to///destination
printf %s\\n "$PWD"

/path/to/destination

를 사용하면 -P이 스위치는 cd현재 작업 디렉터리에 대한 절대 물리적 경로가 로 설정되도록 합니다 $PWD. 그렇지 않으면 -L또는 기본적으로 cd셸 세션이 진행되는 동안 이전 심볼릭 링크 디렉터리 변경으로 인해 암시된 모든 간접 경로가 유지됩니다.

따라서 트리를 순회하면 트리에 있는 이름을 가장 안정적으로 수집할 수 있습니다.

관련 정보