이중 탈출을 방지하는 방법은 무엇입니까?

이중 탈출을 방지하는 방법은 무엇입니까?

여러 이미지를 PDF 파일로 병합하려고 합니다. 실행해서 gm convert *.jpg out.pdf성공했는데 이미지 순서가 맞지 않네요. 순서가 맞는
걸 발견해서 시도해 보았지만 , 파일 이름에 공백이 포함되어 있어서 실패했습니다.ls -vgm convert `ls -v *.jpg` out.pdf

그래서 ls 옵션을 확인하고 시도했지만 gm convert `ls -Qv *.jpg` out.pdfgm convert `ls -bv *.jpg` out.pdf다 실패했습니다. 내가 알 수 있는 한 파일 이름이 두 번 이스케이프되었기 때문입니다(첫 번째 경우에는 \"를 사용하고 두 번째 경우에는 공백 \\ 이전).
왜 이런 일이 발생하고 파일 이름을 올바르게 이스케이프하려면 어떻게 해야 합니까? 즉, zsh를 한 번만 사용하는 것입니다(해당되는 경우).

답변1

이대로는 탈출할 수 없습니다. 셸 구문 분석과 같이 따옴표나 백슬래시를 사용하여 이해할 수 있습니다.

명령 대체 중에 변수 확장이나 토큰화를 피할 수 있는 것은 없습니다(명령줄의 셸 구문 분석(토큰화)과 달리).

할 수 있는 일은 내부 필드 구분 기호를 $IFS개행 문자로만 분할하도록 변경하는 것입니다(그러나 파일 이름에 와일드카드 문자가 포함되지 않는다고 보장할 수 없는 한 명령 대체 시 수행해야 할 또 다른 사항 zsh*.jpg

set -f # disable filename generation
IFS='
' # set IFS  to newline character
IFS=$'\n' # alternative for ksh/zsh/bash
gm convert $(set +f; ls -v ./*.jpg) out.pdf # you also need ./ in case file
                                            # names start with -

(모든 파일 이름에 개행 문자가 포함되어 있지 않다고 가정)

set -fin zsh(sh/ksh 에뮬레이션 제외)은 rc파일 읽기(생각 zsh -f) 를 비활성화합니다 csh -f. 이는 쉘이 시작된 후에는 아무런 효과가 없으므로 무해합니다.

를 사용하면 zsh다음과 같이 단축할 수 있습니다.

gm convert ${(f)"$(ls -v ./*.jpg)"} out.pdf

(f)약어는 (ps:\n:)개행 문자로 구분됩니다.

또는 ls따옴표를 사용하여 셸 명령줄(또는 원하는 경우 셸 구문의 셸 코드)을 빌드하여 전달하고 eval셸에서 이를 평가하고 실행하도록 할 수 있습니다.

ksh93, 또는 :zshbash

eval "images=($(ls --quoting-style=shell -v ./*.jpg))"
gm convert "${images[@]}" out.pdf

그러나 를 사용하면 zsh다음과 같이 간단히 수행할 수 있습니다.

gm convert ./*.jpg(n) out.pdf

(n)생성된 파일 이름을 숫자로 정렬하도록 쉘에 지시하는 와일드카드 한정자입니다.

관련 정보