변수를 사용하여 스크립트에서 디렉터리를 변경할 수 없습니다.

변수를 사용하여 스크립트에서 디렉터리를 변경할 수 없습니다.

내 스크립트:

#!/bin/sh

_directory1="/home/user/test1"
_directory2="test2"

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

그리고 여기에 오류가 있습니다.

./myscript.sh: 6: cd: can't cd to /home/user/test1/test2

내가 도대체 ​​뭘 잘못하고있는 겁니까?

답변1

편집 전 원본 코드:

#!/bin/sh

_directory1="~/test1"
_directory2="test2"

for i in $(cd "${_directory1}/$_directory2")
do
    echo "$i"
done
  1. 물결표( ~)는 변수처럼 동작하지 않습니다. 예를 들어, 따옴표 안에 사용하면 홈 디렉터리 경로로 확장되지 않습니다. 스크립트에서는 $HOME물결표 대신 사용하세요. ~명령줄에서 사용할 수 있는 "단축키"이지만 $HOME스크립트에서 더 설명적입니다.

  2. cd는 루프할 수 있는 내용을 출력하지 않으므로 cd명령 대체에 다음을 사용하면 for아무 소용이 없습니다. 불행하게도 루프가 실제로 무엇을 하길 원하는지 불분명하므로 확실한 대체 구현을 제공할 수 없습니다.


수정한 코드:

#!/bin/sh

_directory1="/home/user/test1"
_directory2="test2"

cd "${_directory1}/$_directory2"

for i in *
do
    echo "$i"
done

이 코드는 다음과 같이 출력됩니다.

"./myscript.sh: 6: cd: can't cd to /test2"

변수 이름의 철자를 잘못 입력한 경우 _directory1(그리고 철자가 잘못된 변수는 비어 있고 디렉터리 /test2가 존재하지 않는 경우)


그런 다음 오류 메시지를 편집했습니다.다시출력된다고 합니다

./myscript.sh: 6: cd: can't cd to /home/user/test1/test2

이는 단순히 디렉토리가 /home/user/test1/test2존재하지 않음을 의미합니다. 귀하는 이 디렉토리에 대한 증거를 제공하지 않았습니다.하다존재하므로 우리는 이에 대해 귀하의 시스템의 말을 받아들여야 합니다.


다음은 디렉토리의 내용을 나열하는 스크립트입니다(디렉토리가 존재한다고 가정). 코드는 각 파일의 전체 경로 이름을 인쇄합니다.

#!/bin/bash

topdir=$HOME/test1
subdir=test2

printf '%s\n' "$topdir/$subdir"/*

또는,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

for name in "$topdir/$subdir"/*; do
    printf '%s\n' "$name"
done

nullglob옵션은 주어진 패턴이 어떤 것과도 일치하지 않으면 루프가 전혀 실행되지 않도록 만듭니다. 옵션을 설정하지 않으면 nullglob일치하는 항목이 없으면 패턴이 확장되지 않은 상태로 유지되며 루프는 이를 $name단일 반복의 값으로 사용합니다.

숨겨진 이름( 문자로 시작하는 파일 이름) 에 관심이 있는 경우 dotglob쉘 옵션( )을 설정할 수도 있습니다 .shopt -s dotglob.

또는 각 파일 이름의 전체 경로를 인쇄하지 않고

#!/bin/bash

topdir=$HOME/test1
subdir=test2

cd "$topdir/$subdir" || exit 1

printf '%s\n' *

exit 1실패 하면 스크립트가 종료 됩니다 cd.

또는,

#!/bin/bash

topdir=$HOME/test1
subdir=test2

cd "$topdir/$subdir" || exit 1

shopt -s nullglob

for name in *; do
    printf '%s\n' "$name"
done

다음을 사용하지 않고 전체 경로 없이 파일 이름만 인쇄하려면 cd:

#!/bin/bash

topdir=$HOME/test1
subdir=test2

shopt -s nullglob

for name in "$topdir/$subdir"/*; do
    printf '%s\n' "$( basename "$name" )"

    # or:  printf '%s\n' "${name##*/}"

done

이는 basename유틸리티를 사용하여 경로 이름의 파일 이름 부분만 추출합니다. 주석의 대안은 표준 매개변수 대체인 를 사용하여 ${name##*/}파일 이름 앞의 초기 디렉토리 경로를 삭제합니다(문자 그대로 "패턴과 일치하는 가장 긴 접두사 문자열을 제거 */" $name).

관련 정보