cd
파일을 이동하고 대상 디렉터리로 따라갈 수 있는 스크립트(보다 정확하게는 별칭)를 작성하려고 합니다 . 이것수락된 답변이 문제에는 다음 코드를 사용하는 것이 좋습니다.
mvf() { mv "$@" && goto "$_"; }
여기서 는 goto
and 의 더 안전한 변형이며 마지막 명령에 전달된 마지막 인수입니다.cd
$_
내 파생 구현은 다음과 같습니다.
alias mvaf="mv $@ && cd $_"
$@
모든 매개변수를 사용하여 이름별로 파일을 이동하는 것을 방지하기 위해 따옴표가 없습니다 . 처음에 이것의 변형을 시도했지만 스크립트도 실패했습니다. 위의 구현을 호출하면 mvaf test1 test2 ..
"mv: 누락된 파일 피연산자"가 발생합니다(번역됨).
디버깅할 때 를 사용하지 않으려고 시도했는데 cd
실제로 alias mvaf="mv $@ "
는 기본적으로 이름이 바뀌고 mv
파일이 이동되었습니다.
이제 mv
첫 번째 구현에서 피연산자가 누락된 이유와 이것이 &&
.
답변1
별칭은 $@, $1, $2 등과 같은 피연산자를 지원하지 않습니다.
주문
alias mvaf="mv $@ && cd $_"
별칭이 예상한 방식으로 인식되지 않기 mv ' ' && cd $_
때문에 같습니다 .$@
이는 다음과 같이 쉽게 증명할 수 있습니다.
$ alias mvaf='echo "Part 1:" $@ && echo "Part 2: " $_'
$ mvaf file66 /tmp/
Part 1:
Part 2: Part 1: file66 /tmp/
#Part 2 includes the previous executed command (echo "Part 1:" $@) & the text sent after alias name
$ alias mvaf='echo "Part 1:" $@;echo "Part 2: "'
$ mvaf file66 /tmp/
Part 1:
Part 2: file66 /tmp/
반면에 이것은 작동하지만 $@ 때문에 작동하지 않습니다.
$ alias mvaf='echo "mv $@"'
$ mvaf file66 /tmp/
mv file66 /tmp/
$ alias mvaf='echo "mv"'
$ mvaf file66 /tmp/
mv file66 /tmp/
일반적으로 별칭은 간단한 대체입니다.
Alias aa='command1;command2'
, aa sometext
동일하게 호출되는 경우command1;command2 sometext
이 작업을 수행하려면 함수를 사용해야 합니다. Bash는 별칭 사용을 권장하지 않으며 이러한 종류의 작업을 수행하기 위해 함수 사용을 권장합니다. 이 함수를 bash 구성 파일에 붙여넣고 별칭처럼 터미널에서 직접 이름으로 호출할 수 있습니다.
mvcd() { mv "$1" "$2" && cd "$2"; }
여기서는 이전 명령이 성공한 경우에만 두 번째 명령이 실행되도록 하기 때문에 링크 mv
와 cd
명령이 &&
중요합니다.&&
cd
mv
아니면 이미 제안한 대로귀하의 질문에 허용된 답변에 대한 링크에서, 당신은 다음과 같은 것을 할 수 있습니다
mvf() { mv "$@" && goto "$_"; }
goto() { [ -d "$1" ] && cd "$1" || cd "$(dirname "$1")"; }
bash 분사에 주의하세요. 이와 같은 기능이 제대로 작동하려면 이동 중인 파일이나 전송되는 파일의 디렉터리 이름에 공백이 포함된 경우 해당 기능 호출 시 큰따옴표를 넣어야 합니다.
$ mvcd() { echo "1=$1";echo "2=$2";echo "3=$3";echo "4=$4"; }
$ mvcd spaced file1 /spaced directory/
1=spaced
2=file1
3=/spaced
4=directory/
$ mvcd "spaced file1" "/spaced directory/"
1=spaced file1
2=/spaced directory/
3=
4=
답변2
alias
$@
또는 $_
(또는 )은 특별한 것으로 간주되지 않으므로 $anything
그대로 쉘에 전달됩니다.
따라서 원본은 다음과 같습니다.
alias mvaf="mv $@ && cd $_"
의미는 다음과 같습니다
mvaf f dst/
이 되다:
mv $@ && cd $_ f dat/
$@
및 는 $_
정의될 가능성이 없으므로 쉘은 이를 다음과 같이 해석합니다 .
mv && cd f dat/
따라서 mv
인수 없이 호출하면 "파일 피연산자 누락" 오류가 발생합니다.
다음과 같이 재정의하면:
alias mvaf="mv $@ "
그리고 다음을 실행합니다:
mvaf f dst/
그것은 다음과 같이 된다:
mv $@ f dst/
이전과 마찬가지로 다음과 같이 단순화됩니다.
mv f dst/
그리고 그것이 효과가 있었다고 생각하도록 속이세요!
답변3
@Deathgrip이 댓글에 썼듯이,
대체 텍스트에 매개변수를 사용하는 메커니즘은 없습니다. 매개변수가 필요한 경우 쉘 함수를 사용해야 합니다(아래 함수 참조).
별칭은 어떻게 작동하나요?
명령줄에 다음 두 줄을 입력하면 어떤 일이 발생하는지 생각해 보겠습니다.
$ alias word1="echo example"
$ word1 word2 word3
첫 번째 명령을 실행한 후에는 명령 bash
이 나올 때마다 word1
해당 명령의 첫 번째 단어로 바꿔야 한다는 점을 기억하세요 echo example
. 두 번째 명령을 보면 먼저 가능한 가장 어리석은(가장 간단한) 방법으로 대체를 수행합니다. 즉, echo example word2 word3
해당 입력에서 명령을 생성합니다. 그래서 응답이 있었습니다 example word2 word3
.
이제 귀하의 별칭은 어떻게 되나요?
그것을 보면 mfav one two
평가한다 mv $@ && cd $_ one two
. 비어 있어서 실패합니다 $@
( echo $@
콘솔에서 시도) . 또한 두 개 이상의 인수를 받았기 때문에 실패합니다.mv
cd
참고: 내 글은 지나치게 단순화되어 별칭은 첫 번째 단어만 대체합니다. 이 규칙을 위반한 경우,내 다른 답변보기.
답변4
다른 모든 답변은 별칭이 작동하지 않는 이유를 설명하고 George Vasiliu의 답변은 작업을 수행하는 대체 기능을 제공합니다.
그러나 저는 이 답변을 바탕으로 더욱 강력하게 만들고 싶습니다. 현재 이 기능은
mvcd() { mv "$1" "$2" && cd "$2"; }
대상이 파일인 경우 효과가 없습니다. 이 문제를 해결하기 위해 bash 변수 하위 문자열 표기법을 사용할 수 있습니다.
mvcd() { mv "$1" "$2" && [[ -d $2 ]] && cd $2 || cd ${2%/*}; }
여기서 무슨 일이 일어나고 있는지 확인하기 위해 더 읽기 쉬운 형식으로 작성해 보겠습니다.
mvcd () {
mv "$1" "$2"; # Do the move
if [[ -d $2 ]] # Check if arg $2 is a dir
then
cd $2; # if it is, cd into it
else
cd ${2%/*}; # else remove the filename and cd
fi;
}
대상이 디렉터리 [1]인지 확인합니다. 그렇다면 디렉터리로 CD를 넣습니다. 그렇지 않은 경우 두 번째 인수를 처음부터 맨 오른쪽까지 부분 문자열로 묶고 /
그 안에 넣습니다.
[1] 조건 없이 이 작업을 수행하려고 dirname과 readlink를 함께 묶거나 항상 경로나 다른 해킹을 앞에 추가하는 등 많은 시간을 낭비했지만 ./
항상 문제에 부딪혔습니다. of readlink) 또는 cding to 에서는 작동하지 않습니다 ..
. 또는 파일 이름에서는 작동하지 않습니다. 예. 누구든지 문자열 없이 이 작업을 수행할 수 있다면 제안에 열려 있습니다.