Bash 스크립트가 별칭을 인식하지 못하는 이유는 무엇입니까?


216

~/.bashrc파일 에는 두 가지 정의가 있습니다.

  1. commandA더 긴 경로의 별칭 인
  2. commandBBash 스크립트의 별칭 인

이 두 명령으로 동일한 파일을 처리하고 싶기 때문에 다음 Bash 스크립트를 작성했습니다.


#!/bin/bash

for file in "$@"
    do
    commandA $file
    commandB $file
done

세션에서 로그 아웃했다가 다시 로그인 한 후에도이 command not found스크립트를 실행할 때 Bash 에서 두 명령 모두에 대한 오류 메시지가 표시됩니다 .

내가 무엇을 잘못하고 있지?


10
BTW, 별칭을 인식하기 위해 로그인하거나 로그 아웃 할 필요가 없습니다. 당신은 그냥해야 source ~/.bashrc합니다.
tshepang

내 경우에는 SSH 에이전트를 닫고 다시 연결했을 때 별칭을 추가 한 후 SSH 에이전트로 원격으로 연결되었습니다.
dav

별명은 명령을 단축하는 방법입니다. 스크립트는 대화식 쉘에서만 사용되며 스크립트에서는 사용되지 않습니다. 이는 스크립트와 대화식 쉘의 차이점 중 하나입니다.
Kris Roofe

답변:


117

우선, ddeimeke가 말했듯이 기본적으로 별칭은 비 대화식 쉘에서 확장되지 않습니다.

둘째, 환경 변수 .bashrc를 설정하지 않으면 비 대화식 쉘에서 읽지 않습니다 BASH_ENV.

그러나 가장 중요한 것은 그렇게하지 마십시오! 부디? 어느 날 필요한 별칭이 설정되지 않은 곳으로 스크립트를 옮기면 다시 끊어집니다.

대신 스크립트에서 환경 변수를 바로 가기로 설정하고 사용하십시오.

#!/bin/bash

CMDA=/path/to/gizmo
CMDB=/path/to/huzzah.sh

for file in "$@"
do
    $CMDA "$file"
    $CMDB "$file"
done

5
이 솔루션은 일반적인 alias사용 사례 에서는 작동하지 않습니다 . 예 alias mv="mv -v --backup=numbered".
Evi1M4chine

@ Evi1M4chine : 그렇습니다. 적어도 내가 Gilles를 불필요한 편집으로 되 돌린 후에. 그러나 어쨌든 매개 변수에 다른 변수를 사용하는 것이 좋습니다.

1
아, 주위에 따옴표 가 없음 을 주목하십시오 $CMDA/ $CMDB… bash에서 bash 자체를 위해 예약 된 대문자 변수와는 별도로 실제로 따옴표가 없기 때문에 정말 불안합니다 ... 어쨌든 감사합니다.
Evi1M4chine

@ Evi1M4chine : 어, 뭐? 1. 가장 최근의 편집에서 따옴표를 제거했습니다. 2. "bash 자체를위한 예약"은 어디에서 얻습니까? 이것이 내가 들어 본 첫 번째 것입니다. 3. 만약 이것이 당신을 불안하게 한다면 , 처음에 bash를 사용하는 것에 대해 어떻게 생각하십니까? 어쨌든, 내가 말했듯이 옵션에 별도의 변수를 사용하십시오.

1
@alvas : gizmo경로에 없거나 이름이 같지만 우선 순위가 높은 명령 이 있다고 가정 합니다. 그렇지 않으면 처음에는 단순 CMDA하게 일반 gizmo으로 설정할 수 있습니다.

161

bash 맨 페이지를 보면 다음을 찾을 수 있습니다.

expand_aliases 쉘 옵션이 shopt를 사용하여 설정되지 않는 한 쉘이 대화식이 아닌 경우 별명은 확장되지 않습니다 (아래의 SHELL BUILTIN COMMANDS에서 shopt에 대한 설명 참조).

그래서 넣어

shopt -s expand_aliases

스크립트에서.

스크립트에서 별칭 파일을 설정 한 후 별칭 파일을 제공해야합니다.

shopt -s expand_aliases
source ~/.bash_aliases

7
스크립트에 넣었지만 여전히 작동하지 않습니다. 같은 오류입니다.
Zaid

5
추가 shopt -s expand_aliases source ~/.bash_aliases나를 위해 완벽하게 작동합니다. # If not running interactively, don't do anything [ -z "$PS1" ] && return@Zaid, 아마도 당신이 소스 파일에서 그것을 확인하고 싶을 때 .bashrc에 대화 형 쉘 감지의 형태가 종종 있습니다 .
Frank Schubert

1
우수한! 내 스크립트를 저장했습니다 !! :) 터미널에서 정보와 맨 페이지를 읽거나 검색하기가 너무 어려워 방금 전에 포기하고 인터넷에서 검색을 할 수 있습니다 ...
Aquarius Power

2
흥미롭게도 shopt -s expand_aliases별칭 정의 전에 가야하지만 별칭을 사용하기 전에 가야합니다. @FrankSchubert에 추가 : 특히 쉘이 대화 형인 경우 $-쉘에 대한 옵션이 포함 된 대화식 쉘 감지를 수행 할 수도 있습니다 i.
유효한

2
이것은 정답이 아닙니다 ... 스크립트 내에서 별칭을 소싱하는 것이 답이 아닙니다. 귀하는 ~/.bash_aliases이전에 대화 형 쉘에로드 된 다른 것들에 의존 할 수 ... 내가 찾은 가장 가까운 것은 당신의 hashbang을 변화 #!/bin/bash -li완벽하지 아직도. 이상적으로는 별칭이 아닌 함수를 사용해야합니다.
Stefanos Kalantzis

44

별칭은 내보낼 수 없으므로 정의되지 않은 셸 스크립트에서는 사용할 수 없습니다. 다시 말해서, 그것들을 정의하면 ~/.bashrc사용할 수 없습니다 your_script.sh( ~/.bashrc스크립트에서 소스 를 작성 하지 않는 한 , 권장하지는 않지만 올바르게 수행하는 방법이 있습니다).

그러나 함수를 내보내고 정의 된 환경에서 실행되는 쉘 스크립트에서 사용할 수 있습니다. 이것을 bashrc에 배치하면됩니다.

foo ()
{
    에코 "Hello World!"
}
내보내기 -f foo

Bash 매뉴얼에 따르면, "거의 모든 목적에 따라 별칭보다 쉘 기능이 선호됩니다."


1
이 기술적 질문에 대답하지 않지만, 당신은 당신이 간단하게 교체 할 수 있습니다 말한대로 alias commandA=...commandA() { ... }다음 export commandA당신은 별명과 동일한 동작을 얻을. 따라서 이것은 내가 bash 스크립트에서 잘 작동한다는 것을 알기
만하더라도

여기서 문제는 인용 된 많은 옵션을 전달하는 별칭이 필요할 때입니다. 예를 들어 기능에서 수행하기 어려운 alias b=bash작업 b -c "echo test | grep test"을 쉽게 수행 할 수 있습니다.
Fmstrat

@Fmstrat : b () { bash "$@"; }그때b -c "echo test | grep test"
Dennis Williamson

11
[cmd line] > bash -i [your script's file path]

i상호 작용을위한 당신의 소싱 bash당신을 위해 프로필을.


-5

bash 스크립트가 내보내기를 인식하지 못하는 경우가 있습니다. 그러나로 변경

#!/bin/sh

나를 위해 작동합니다.


1
아니, 그것은 ...
Hafiz Temuri
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.