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

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

내 스크립트:

#!/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명령 대체에서 with를 사용해도 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옵션이 설정되지 않은 경우 if가 아무것도 일치하지 않으면 패턴은 확장되지 않은 상태로 유지되며 루프는 $name이를 단일 반복에서 for의 값으로 사용합니다.

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").

관련 정보