bash 별명을 확장하는 방법


11

Bash에서 동일한 이름의 다른 별칭을 실제로 확장하는 별칭을 만드는 방법은 무엇입니까?

왜:

나는 다음과 같이 GREP_OPTIONS설정했다 .bashrc.

GREP_OPTIONS="-I --exclude=\*~"

또한 setup-java.sh일부 Java 프로젝트를 수행하기 전에 호출 할 스크립트 (우리에게 말해 주겠다 )가있었습니다. 다음 줄이 포함됩니다.

GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=classes"

Sass도 사용한다면 다음 setup-sass.sh을 포함하는 라인을 호출 합니다.

GREP_OPTIONS="$GREP_OPTIONS --exclude-dir=\*/.sass-cache"

그러나 GREP_OPTIONS더 이상 사용되지 않으며 분명히 표준 솔루션은 별칭 또는 스크립트를 만드는 것입니다 ...


bash 함수는 어떻습니까?
Jakuje

2
나는 동의합니다. 함수를 사용하는 것이 별칭보다 훨씬 나은 옵션입니다.
Charles Duffy

답변:


13

Bash는 별칭이라는 값을 다음과 같은 배열 BASH_ALIASES 에 저장합니다 .

$ alias foo=bar
$ echo ${BASH_ALIASES[foo]}
bar

매개 변수 확장 우리는 (있는 경우) 중 마지막 세트 별칭을 얻을하거나 기본값을 수행 할 수 있습니다 :

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~"

이제 그냥하십시오 setup-java.sh:

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~  --exclude-dir=classes"

... 그리고 마지막으로 setup-sass.sh:

alias grep="${BASH_ALIASES[grep]:-grep} -I --exclude=\*~ --exclude-dir=\*/.sass-cache"

세 줄이 호출되면 원하는 것을 얻습니다.

$ echo ${BASH_ALIASES[grep]:-grep}
grep -I --exclude=\*~ -I --exclude=\*~ --exclude-dir=classes -I --exclude=\*~ --exclude-dir=\*/.sass-cache

13

aliases 공백으로 끝내면 체인.

alias print='printf %s\\n ' hey='"hello, fine fellow" '
print hey

hello, fine fellow

당신이 충분히 미쳤다면 당신은 그런 식으로 전체 스크립트를 작성할 수 있습니다. 어쨌든 별명을 확장하려면 확장하려는 별명을 공백으로 끝내고 다른 별명을 고정하십시오.

alias grep='printf "%s " -I --exclude=\*~ '    \
      exdir=' --exclude-dir=classes '          \
      exsass='--exclude-dir=\*/.sass-cache '
grep exdir exsass exdir exsass

-I --exclude=*~ --exclude-dir=classes --exclude-dir=*/.sass-cache --exclude-dir=classes --exclude-dir=*/.sass-cache

7
이것은 아름답고 끔찍합니다.
user1717828

와, 대단해. 이것을 알지 못했을 것입니다 (그리고 아마도 명확성규칙에 위배된다고 생각하기 때문에 많이 사용하지 않을 것입니다 ). 그러나 질문 : 왜 시작 부분에 공간이 exdir있습니까? (심미적 인 이유로 정렬하는 것입니까?)
Wildcard

2
@ 와일드 카드 : fnmatch(){ alias fnmatch='case $1 in '; while "${1:+:}" 2>&-; do eval 'fnmatch pattern list ;; esac'; shift; done; unalias fnmatch; }; alias pattern='${1:+*}) ' list=': do stuff '; fnmatch "$@". 함께 aliases사용하면 패턴의 확장을보다 직접적이고 안전하게 사용할 수 있습니다. eval함수 내에서 호출 할 때 두 번째 컨텍스트가 필요 하지만 이름 patternlist이름을 제어하는 한 본질적으로 안전하지 않습니다 . 일부 공격자가 의도적으로를 종료하지 않는 한 대부분의 경우에만 침입 할 수 있습니다 case.
mikeserv

1
패턴 에서이 패턴 을 사용합니다 .bashrc. alias sudo='sudo '이렇게하면 별칭 뒤에 모든 별칭 명령을 호출 할 수 있습니다 sudo. 공간이 없으면 작동하지 않습니다
arainone

1
@Wildcard-나는 그런 사용을 정확하게 옹호하지는 않았지만, 당신이 할 수있는 것은 사실이며, 시도하기에는 적어도 미쳤어 야한다는 것이 사실입니다.
mikeserv

2

여기서 함수는 확장 가능한 별칭보다 더 나은 옵션입니다.

grep_options=( )
grep() {
  exec /usr/bin/grep "${grep_options[@]}" ${GREP_OPTIONS} "$@"
}

이렇게하면 환경에 옵션을 추가 할 수있는 두 가지 옵션이 있습니다.

  • grep_options배열을 수정하십시오 . 공백, 리터럴 글로브 문자 및 기타 코너 경우 옵션을 올바르게 지원합니다.

    grep_options+=( --exclude-dir=classes --exclude-dir='*/.sass-cache' )
  • GREP_OPTIONS함정에도 불구하고 전통적인 스칼라 변수를 사용하십시오 ( 이 중 일부를 이해 하려면 BashFAQ # 50 참조 ).

    GREP_OPTIONS+=' --exclude-dir=classes '

즉, grep쉘 외부에서 호출 된 인스턴스에 옵션을 반영 하려면 별칭이나 함수가 수행하지 않습니다. 대신 실제 grep명령 보다 PATH에 래퍼 스크립트를 배치하는 것이 좋습니다. 예를 들어 :

# in ~/.bash_profile
[[ -e ~/bin ]] && PATH=$HOME/bin:$PATH

...에서 ~/bin/grep:

#!/bin/bash

# load overrides to grep_options on GREP_OPTIONS from local dotfiles
source ~/.bash_profile
source ~/.bashrc

# ...and use them:
exec /usr/bin/grep "${grep_options[@]}" ${GREP_OPTIONS} "$@"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.