공백이 포함된 일부 문자열 변수를 매개변수로 프로그램에 전달하는 데 어려움이 있습니다.
전달되는 인수를 디버깅하고 표시하기 위해 데모 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
셸 세션이 진행되는 동안 이전 심볼릭 링크 디렉터리 변경으로 인해 암시된 모든 간접 경로가 유지됩니다.
따라서 트리를 순회하면 트리에 있는 이름을 가장 안정적으로 수집할 수 있습니다.