좋아요 -bash: cd ..: command not found
.
지정된 디렉터리를 반복하는 스크립트를 작성했습니다. 항상 효과가 있었지만 지금은 무엇이 바뀌었는지 모르겠습니다.
$ type up
up is a function
up ()
{
local arg="$@";
if [ -z "$arg" ]; then
cd ..;
return 1;
fi;
local arr=();
local sep='/';
local IFS="$sep";
local DIRS;
read -ra DIRS <<< "$(pwd)";
for ((i=${#DIRS[@]}-1; i>=0; i-- ))
do
if [ "${DIRS[i]}" = "$arg" ]; then
local first=${arr[0]};
arr=("${arr[@]:1}");
$(printf "%s" "cd $first" "${arr[@]/#/$sep}" && echo "/");
return 1;
else
arr+=('..');
fi;
done;
echo "Directory \"$arg\" could not be found in path. Check spelling and try again." 1>&2;
return 0
}
속도
- 매개변수가 전달되지 않으면 이전 디렉터리로 이동합니다.
- 매개변수가 전달되는 경우:
잡아서
pwd
분리해/
대기열 뒤에서 오는 디렉터리 목록을 반복합니다.
현재 디렉터리가 매개변수와 일치하지 않으면
..
목록에 추가하세요.dir이 명령줄 arg와 일치하는 경우
..
로 구분된 압축을 풀고/
문자열을 명령으로 실행합니다.printf "%s" "cd $first" "${arr[@]/#/$sep}" && echo "/" # printf "%s" "cd $first" : prints 'cd ..' (command & the first placeholder) # "${arr[@]/#/$sep}" : prints the remaining '..' joined by '/' # echo "/" : adds a trailing '/' to the relative path # which could have been included in the # previous step but separated for comprehension # Given, pwd = /Users/dev/workspace/project/foo # `up workspace` navigates to 'cd ../../'
디버깅(터미널에서)
> cd ..
# works as expected
> $(echo "cd ..")
# works as expected --> maybe something with the "/" is breaking it?
> $('cd ..')
# -bash: cd ..: command not found
> $('cd ../')
# -bash: cd ../: No such file or directory
> which cd
# /usr/bin/cd
> echo $PATH
# /usr/bin
> type cd
# cd is a shell builtin
> alias cd
# -bash: alias: cd: not found
> shopt expand_aliases
# expand_aliases on
OSX의 bash3.2에서는 대부분의 환경 변수(예: CDPATH)를 설정 해제하거나 깨끗한 환경(예:)으로 셸을 여는 것이 env -i bash --noprofile --norc
도움이 되지 않습니다.
논평
내 bash는 약간 녹슬었으므로 이를 유지 관리할 수 있는 더 나은 방법을 자유롭게 지적해 주십시오. 나는 그것이 아마도 필요하지 않거나 정확하지 않다는 것을 알고 있으며 더 효율적일 수 있지만 따르기가 더 어려운 return
일부 구현을 보았습니다 .find
답변1
$(echo "cd ..")
쉘 명령 echo "cd .."
(예: echo
단일 인수가 있는 명령 cd ..
)을 실행하고 출력( cd ..
)을 얻은 다음 해당 출력을 공백(및 와일드카드, 여기서는 중요하지 않음)으로 분할하고 두 단어의 합계를 얻은 cd
다음 인수를 사용 ..
합니다 . 이는 단지 쉘 명령을 실행하는 복잡하고 오류가 발생하기 쉬운 방법입니다 .cd
..
cd ..
와는 별개로여기서 슬래시를 설정하면 IFS
단어가 부분으로 분할됩니다.공백으로 나누지 말고 슬래시로 나누세요..
따라서 예를 들어 을 실행하면 $(echo "cd ../..")
명령 대체 결과가 로 분할되지 않고 cd
, ../..
로 분할 됩니다 cd ..
. 여기에 있는 공백은 이제 쉘 명령줄에 입력하는 ..
것처럼 명령 이름의 일부가 됩니다 ."cd .." ..
단어 분리에 의존하지 않고(특히 디렉토리 이름에 공백이 포함된 경우 분리되므로) 명령과 인수를 분리하는 것이 좋습니다. 변수에 디렉토리 이름을 작성하고 사용하십시오. 예:
dir=$(printf "../..")
cd -- "$dir"
아니면 더 정확하게는
printf -v dir "../.."
cd -- "$dir"
또한 아마도 거기에 있을 필요도 없을 것입니다 printf
. 를 사용 "${arr[*]}"
하면 의 첫 번째 문자와 연결된 배열 요소를 가져올 수 있으므로 를 IFS
사용하면 IFS=/
슬래시로 연결됩니다.
예를 들어:
arr=(.. .. ..)
IFS=/
dir="${arr[*]}"
dir
로 설정 ../../..
.