루프 변수의 출력이 예상과 다른 값을 표시합니다.

루프 변수의 출력이 예상과 다른 값을 표시합니다.

back/현재 작업 디렉토리에 와 이라는 두 개의 폴더가 있다고 가정해 보세요 front/. 나는 그들 각각의 안으로 들어가서 뭔가를 하려고 노력했다. 아래의 간단한 스크립트에서:

for dir in */ ; do
    echo "$(dir)"
done

나는 다음과 같은 결과를 기대하고 있습니다 :

back
front

그러나 내가 얻는 것은 다음과 같습니다.

back  front
back  front

난 이해가 안 돼요. 결과는 cd폴더에 들어가려고 하면 다음과 같습니다 .

for dir in */ ; do
    echo "$(dir)"
    cd $(dir)
    echo "$(pwd)"
    cd ..
done

나는 얻다:

back  front
/path/to/back
back  front
/path/to/back

즉, 나는 결코 들어가지 않는다 front/. 누군가 내가 뭘 잘못하고 있는지 이해하도록 도와줄 수 있나요?

답변1

POSIX와 유사한 셸에서 $(cmd)구문은 다음과 같습니다.명령 대체$(cmd), 후행 줄 바꿈을 뺀 출력 으로 확장됩니다 .cmd

당신이 원하는 것은매개변수 확장: $dir또는 ${dir}(여기서 매개변수는dir 바꾸다).

pwd( print working dicory)는 1개의 특수 변수의 내용을 출력하는 명령입니다. $PWD이 변수 ​​자체에는 현재 작업 디렉터리에 대한 경로가 포함되어 있으므로 $(pwd)줄 바꿈으로 끝나지 않는 한 동일한 내용으로 확장됩니다.$PWD$PWD

그래서 당신은 다음을 원합니다:

for dir in */; do 
  (
    printf '%s\n' "$dir"
    cd -- "$dir" &&
      printf '%s\n' "$PWD"
  )
done

또는:

for dir in */; do 
  (
    printf '%s\n' "$dir"
    cd -- "$dir" &&
      pwd
  )
done

또한 기억해주세요

  • echo임의의 데이터를 출력하는 데 사용할 수 없습니다. printf대신 사용하십시오.
  • 일반적으로 명령의 종료 상태를 확인해야 합니다. 여기서 확인되지 않은 출력은 첫 번째 작업이 실패할 경우 다음 작업을 수행하면 잘못된 위치로 이동한다는 cd의미입니다 .cd ..cd
  • cd후자가 항상 초기 위치로 돌아가는 것을 보장하지 않기 때문에 서브셸에서 실행(사용)하는 것이 더 낫습니다 (...)( 심볼릭 링크가 포함되거나 일부 경로 구성 요소의 이름이 간격에서 변경된 경우).cd ..
  • --비옵션이 시작되지 않는다는 보장이 없는 경우 -(또는 일부 명령에서도 문제가 될 수 있는 경우) +옵션과 비옵션을 구분하는 데 사용해야 합니다 .
  • POSIX와 유사한 쉘에서는 매개변수 확장 및 명령 대체(산술 확장 포함)를 따옴표로 묶어야 합니다. 그렇지 않으면 일반적으로 원하지 않는 암시적 분할+glob이 발생합니다(zsh 제외).

또한 bash(및 zsh를 제외한 다른 POSIX 쉘)에서는 glob이 어떤 파일과도 일치하지 않으면 확장되지 않습니다.

따라서 현재 작업 디렉토리에 다음 유형으로 판별될 수 있는 숨겨지지 않은 파일이 포함되어 있지 않은 경우목차, */전역 패턴은 */빈 목록 대신 자체적으로 확장되며 디렉터리 cd에 들어갈 수 없기 때문에 오류가 표시될 수 있습니다 */.

에서는 glob 한정자를 zsh사용할 수 있습니다 (또는 로 끝나지 않음 ).Nfor dir in */(N); do...for dir in *(N-/); do...$dir/

ksh93에서: for dir in ~(N)*/; do....

에서는 이 옵션을 전역적으로 일시적으로 설정할 bash수 있습니다 .nullglob

shopt -s nullglob
for dir in */; do
  ...
done
shopt -u nullglob

완전성을 위해 $(var)구문은 다음과 같습니다.매크로Makefiles 명령에서 사용되는 확장자입니다 make.

awk언어 에서 는 $필드를 역참조하는 단항 연산자이며 간단히 변수를 var참조하는 데 사용됩니다. awk따라서 $(var)or 와 동일 하며 번째 필드(또는 0인 경우 전체 레코드)로 확장됩니다.$var$ varvarvar

유사한 셸 에서는 rc, 와 동일한 기능 $(var)도 작동합니다. 이는 전달된 단일 요소 목록이므로 일반적으로 를 사용하더라도 변수를 역참조합니다.$var$ var$ 'var'$ ( 'var' )$var$var

TCL에서 $(var)키 이름이 비어 있는 배열 변수의 값으로 확장합니다 var.

$ tclsh
% array set {} {foo 1 bar 2}
% puts $(foo)
1

예, 이 경우 P린트는 별 의미가 없습니다. (70년대 중반 Unix V5의) 명령이 첫 번째라고 P추측할 수 있습니다 .pwd$PWD논리적POSIX에 지정된 현재 작업 디렉토리의 처리는 나중에 나왔습니다(1980년대 초 ksh에서는 실제로 pwd별칭이었고(예, 따옴표가 빠졌습니다!) 문서에서는 resent orking icory로 축약되었습니다). 동일한 목적을 위한 (현재 orking 디렉터리) 변수가 있습니다.print - $PWD-r$PWDPWDtcsh$cwdcwd

관련 정보