명령 대체에서 매개변수를 사용할 때 토큰화

명령 대체에서 매개변수를 사용할 때 토큰화

명령 대체에 사용될 때 공백이 포함된 인수가 올바르게 처리되도록 하려면 어떻게 해야 합니까? 아마도 설명할 예가 있을 것입니다.

$ file="/home/1_cr/xy z"
$ basename $file
xy

$ #need to pass basename a quoted $file to prevent the z in 'xy z' from being eaten
$ basename "$file"
xy z

$ #Now using $file inside a command substitution without quoting.....
$ #....the command substitution causes 'xy z' to split
$ set -- $(basename "$file")
$ printf "%s\n" "$@"
xy
z

$ #But quoting the command substitution does not prevent 'xy z'...... 
$ #....from being split before being passed to basename
$ set -- "$(basename $file)"
$ printf "%s\n" "$@"
xy

내가 무엇을해야 하나

$ set -- $(basename $file)
$ printf "%s\n" "$@"

생산하다

xy z   

답변1

모든 변수와 명령 대체에는 큰따옴표를 넣어야 합니다.

set -- "$(basename -- "$file")"

변수의 값을 단어로 분할하고 해당 단어를 전역 패턴으로 처리하면 되돌릴 수 없습니다. 더 이상 공백이 몇 개 있는지 또는 파일 이름이 와일드카드 확장의 결과인지 알 수 없습니다. 햄버거를 소로 되돌릴 수는 없으므로 먼저 소를 도살장으로 보내지 않도록 해야 합니다.

답변2

선택의 폭이 넓습니다.

  1. 사용"$"*반대로"$@"

     set -- $(basename "$file")
     printf "%s\n" "$*"
    
  2. 명령 대체 및 변수 인용

     set -- "$(basename "$file")"
     printf "%s\n" "$@"
    

관련 정보