우연히 bash에서 alias
.
g=date
$g
Mon Jun 27 13:00:40 MYT 2016
작동합니다. 또 다른 예는 다음과 같습니다.
jj="ping yahoo.com"
$jj
PING yahoo.com (98.138.253.109) 56(84) bytes of data.
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=1 ttl=41 time=347 ms
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=2 ttl=41 time=345 ms
64 bytes from ir1.fp.vip.ne1.yahoo.com (98.138.253.109): icmp_seq=3 ttl=41 time=345 ms
이 버전의 bash를 사용하고 있습니다bash --version GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
나는 조사했다스택교환그리고TLDP 복근, 하지만 우리가 이렇게 할 수 있다는 것을 찾지 못했습니다. 그렇다면 이것이 bash의 새로운 기능인가요, 아니면 간과되고 있는 것인가요? 이것이 고려되는가명령 대체?
답변1
대화형 사용 시 쉘은 터미널 장치에서 입력 행을 읽습니다. 한 줄을 입력한 후에는 다음과 같습니다.파싱된으로 분할하여토큰(단어 및 연산자). 그러면 토큰이나 단어가 특정 순서로 확장되거나 해결됩니다.
참고: 일반적으로 고급 Bash 스크립팅 가이드, 온라인 튜토리얼, 책, 심지어 Stack Exchange :)와 같은 중고 소스보다 프로젝트 문서나 산업 사양과 같은 정식 정보 소스를 참조하는 것이 가장 좋습니다. 이러한 중고 소스는 개념을 더 간단한 언어로 소개하고 설명하는 데 유용하지만 일반적으로 공식 문서를 완전하게 만들거나 대체하기 위한 것은 아닙니다. 중고 자료의 정보도 최신 정보가 아닐 수 있습니다.
이 경우,단순 명령 구문 분석을 위한 POSIX 사양다음과 같이 말합니다
- 변수 할당이나 방향 재지정이 아닌 단어는 확장되어야 합니다. 확장 후에도 필드가 남아 있는 경우 첫 번째 필드는 명령 이름으로 간주되고 나머지 필드는 명령에 대한 인수로 간주됩니다.
그만큼간단한 명령 확장에 대한 Bash 매뉴얼 섹션또한 다음과 같이 말합니다.
- 변수 할당이나 리디렉션이 아닌 단어는 확장됩니다(쉘 확장 참조). 확장 후에도 단어가 남아 있으면 첫 번째 단어가 명령 이름으로 사용되고 나머지 단어는 인수로 사용됩니다.
답변2
이것은 명령 대체가 아닙니다.변하기 쉬운치환. 변수에 명령을 할당하는 것이 아니라 문자열을 할당하는 것입니다. 명령은 할당 시점이 아니라 변수를 사용할 때 실행됩니다.
g=date
문자열을 date
변수에 저장합니다 g
. 그런 다음 를 실행하면 echo "$g"
의 값이 인쇄됩니다 g
( date
뒤에 개행 문자가 표시됨). 왜냐하면 의 값이 첫 번째 인수로 명령 g
에 전달되기 때문입니다. echo
를 실행하면 "$g"
문자열이 date
명령의 첫 번째 위치에 배치되므로 이것이 명령 이름이 됩니다.
에서는 $jj
두 번째 요소가 작용합니다. 변수 확장이 따옴표 바깥에 있기 때문에"분할+글로브 연산자"값에 적용됩니다. 이 경우 이는 값이 jj
공백으로 구분된 두 단어로 분할됨을 의미합니다. 따라서 단어는 ping
명령 위치로 끝나고 해당 단어는 yahoo.com
첫 번째 인수가 됩니다.
답변3
이는 예상되는 동작이며 오랫동안 작동해 왔습니다. 스크립트에서 명령을 작성하는 데 유용합니다.
예를 들어, 일부 입력을 파이프라인으로 보내기 전에 압축 해제를 적용해야 하는 경우도 있지만(나중에 출력에 압축을 적용해야 하는 경우도 있지만) 그렇지 않은 경우도 있습니다. 사용 bash
:
if (( use_compression == 1 )); then
infilter='gzip -d -c'
outfilter='gzip -c'
else
infilter='cat'
outfilter='cat'
fi
$infilter "$indatafile" | somepipeline | $outfilter >"$outdatafile"
명령 대체입니까? 아니요. "명령 대체"는 특히 $(...)
백틱 변형을 출력 내용으로 대체하는 것을 의미합니다.
대신에 이것은매개변수 확장즉, 단순히 매개변수를 해당 값으로 바꾸는 것입니다. 이는 명령이 실제로 실행되기 전에 발생하므로 작동합니다.
이는 다음과 같은 내용이 명령줄에서도 작동한다는 것을 의미합니다.
$ decompress='gzip -d -c'
$ ${decompress/g/gun/} filename >unzippedfilename
( gunzip
대신 실행됩니다 gzip
)
편집하다:별칭 정보.
설명서 bash
에는 다음과 같이 나와 있습니다.
거의 모든 목적에서 별칭은 셸 함수로 대체됩니다.
... 동의합니다.
별칭은 다음과 같은 짧은 작업에 적합합니다.
alias ls="ls -F"
(이것은 내 쉘 세션에서 가지고 있는 유일한 별칭입니다)
명령줄에서 "별칭 지정" 명령을 위해 매개변수 확장을 사용하고 싶지 않을 수도 있습니다. 다른 이유가 아니라면 타이핑하는 데 목이 아프기 때문입니다. 또한 매개변수 확장은 파이프라이닝과 같은 약간 더 복잡한 작업을 수행하는 것을 허용하지 않습니다.
정기적으로 수행하는 다소 복잡한 작업이 있는 경우에는 대신 셸 기능을 사용하세요.
허용되는 답변의 예를 들면 다음과 같습니다.U&L 질문(아래 댓글에 링크되어 있습니다):
alias my_File='ls -f | grep -v /'
이 별칭은 분명히 작동하지만
my_File='ls -f | grep -v /'
$my_File
그런 다음 명령줄에서 명령으로 사용하려고 하면 작동하지 않습니다 (해당 U&L 스레드에서 설명된 이유).
쉘 함수를 사용하면 인수 전달과 같은 작업도 수행할 수 있습니다.
function my_File {
ls -l "$@" | fgrep -v '/'
}
$ my_File -iF symlink
84416642 lrwxr-xr-x 1 kk staff 4 Jun 27 09:03 symlink@ -> file
답변4
이는 단순히 수십 년 동안 (과장 없이) 존재하고 작동해 온 개념인 쉘 변수를 사용하는 것입니다.
명령줄에 변수를 넣으면 쉘이 이를 대체한 다음 명령을 실행하므로 변수가 시작 부분에 있으면 분명히 명령으로 간주됩니다.