숫자 n을 인수로 사용하고 작업 디렉터리에서 ls를 실행하여 나열된 n번째 디렉터리로 디렉터리를 변경하는 명령을 제공하는 bash 스크립트를 만들려고 합니다. 이것이 내가 가진 것입니다:
#! /bin/bash -
arg=$(ls --group-directories-first | awk -v first=$1 'NR == first' | tr -d '[[:space:]]')
cd $arg
이것은 작동하지 않습니다. 실행하면 아무 일도 일어나지 않습니다.
첫 번째 줄은 내가 원하는 방식으로 디렉터리 이름을 캡처하는 것 같습니다. 스크립트를 다음으로 변경하면
#! /bin/bash -
arg=$(ls --group-directories-first | awk -v first=$1 'NR == first' | tr -d '[[:space:]]')
echo $arg
첫 번째 디렉토리가 bin인 디렉토리에서 실행하고 매개변수 1을 지정하면 스크립트는 "bin"을 출력합니다.
[user@manjaro ~]$ ls
bin/
Desktop/
Documents/
Downloads/
[user@manjaro ~]$ cdn 1
bin
그렇다면 원래 버전을 사용할 때 "bin" 없이 CD를 작성하고 bin으로 변경하는 이유는 무엇입니까? 어떻게 바꿔야 하나요?
마지막 요점. 스크립트 외부에서 비슷한 작업을 수행하려고 하면 정상적으로 작동합니다.
[user@manjaro ~]$ foo=bin
[user@manjaro ~]$ cd $foo
[user@manjaro bin]$ pwd
/home/user/bin
또 왜?
답변1
작업 디렉터리는 실행 중인 프로세스의 속성이며 스크립트는 셸과 다른 프로세스에서 실행됩니다. 따라서 스크립트에서 디렉토리를 변경해도 대화형 셸에는 영향을 미치지 않습니다. 이것은 좋은 일입니다. 그렇지 않으면 이와 같은 것이 find
임의의 디렉토리에 쉘을 남길 수 있습니다. 직장에서 방해하는 경우.
실제로 작동하는지, 작업 디렉토리인지 확인하기 위해 pwd
스크립트를 뒤에 넣을 수 있습니다.cd
스크립트다양성. 그런 다음 스크립트가 종료됩니다.
이것을 쉘 함수로 변경하십시오.
cdn() {
arg=$(ls --group-directories-first |
awk -v first="$1" 'NR == first' | tr -d '[[:space:]]')
cd -- "$arg"
}
(당신이 거기에 왜 있는지 잘 모르겠습니다 tr
.)
또는 Bash에서 배열을 사용하세요.
cdn() {
dirs=( ./*/ )
if [[ ${#dirs[@]} == 0 ]]; then
echo "No directories!" >&2
return 1
fi
# minus one to go from one-based to zero-based indexing
cd -- "${dirs[$1 - 1]}"
}
파일 이름에 줄 바꿈이나 공백이 있으면 후자가 더 안전합니다. (주어진 인덱스와 일치하는 디렉토리가 존재하는지 확인하지 않습니다. 존재하지 않으면 단순히 실행하여 cd ''
현재 디렉토리로 "변경"합니다.)