bashrc에서 별칭을 사용하는 동안 가능한 충돌을 테스트하는 방법은 무엇입니까?


12

별칭 명령과 관련된 bashrc 업데이트로 인해 시스템에서 발생한 모든 명령 충돌을 나열하는 간단한 방법이 있습니까?

예를 들어 누군가 alias ls=/path/to/user-generated/executable가 bashrc에 씁니다 . 이것이 실제 명령 ( ls)을 숨기고 있다는 것을 어떻게 알 수 있습니까 ? 한 가지 방법은 bashrc 소싱 전후에 모든 별칭을 실행하고 출력을 비교하는 것 같습니다. 더 좋은 방법이 있습니까?

우분투 12.04를 실행 중입니다.

bash-버전

GNU bash, 버전 4.2.24 (1)-릴리스 (i686-pc-linux-gnu)


참고로 bash와 관련된 질문을 할 때 OS 버전이 아닌 bash 버전을 제공하면 사람들이 대답하는 것이 일반적으로 더 유용합니다.
jordanm

@jordanm 업데이트.
user13107

답변:


8

별명으로 마스킹 된 명령을 찾으려면 다음과 같이하십시오.

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

설명

alias단독으로 정의 된 별명을 나열하고 sed해당 이름을 추출합니다. while 루프는 type -ta각각에서 실행되며 awk별명과 파일이 모두 포함 된 행을 인쇄합니다.


15

typebash가 명령을 해석하는 방법을 찾는 데 사용할 수 있습니다 .


예를 들어 여기 에 type ls인쇄 ls is aliased to `ls --color=auto'합니다.
l0b0

동일하게 작동 which하지만, 쉘 내장이 모두 같은 경우 지금은 아닙니다.
math

@math : type which당신에게 알려주 which is /usr/bin/which므로 내장되어 있지 않습니다. 따라서 무언가가 내장되어 있는지 여부를 알 수 없습니다 (예 : which echotype echo).
choroba

나는 그것이 당신이 사용하는 쉘에 달려 있다고 생각합니다 : type which which is a shell builtin나는 zsh를 사용하고 있습니다.
math

@math : 원래 질문은 / bash로 태그되었습니다.
choroba

7

첫 번째 질문으로, bash는 내부적으로 해시 테이블을 사용하므로 마지막 재정의 만 기록하므로 충돌을 나열하는 방법은 없습니다.

명령이 별명인지 확인하려면, alias ls"찾을 수 없음"과 같은 것을 알리면 별명이 아니고 그렇지 않으면 명령을 사용하십시오.

별칭을 무시하고 원래 함수를 시작하려면 슬래시를 접두사로 붙이십시오 \ls.

편집하다

빠르게 명령 별칭이 있는지 알고 싶은 경우에, 당신은에 의해 모드 디버깅을 가능하게 할 수 set -x당신이 실행하면 현재 ls:

여기에 이미지 설명을 입력하십시오

실행중인 실제 명령의 디버그 출력이 표시됩니다.

디버그 모드를 설정 해제하려면 set -


감사. 그러나 그 alias부분을 얻지 못했습니다 . 사용자가 명령 (예 :)이 있음을 모른다면 어떻게해야 ls합니까? 실행 후 그가 아는 alias ls것만은 원래 매핑 된 것이 아니라 매핑 된 것입니다. 충돌을 찾으려면 \를 사용하거나 사용하지 않고 모든 명령을 실행해야 할 것 같습니다.
user13107

@ user13107 님이 답변을 업데이트했습니다
데이지

감사. 추적을 설정 해제하려면 어떻게합니까?
user13107

@ user13107 다시 업데이트 ;-P
daisy

1
"충돌을 나열 할 방법이 없습니다"– 당신은 상상력이 충분하지 않습니다.
camh

6

bash 내장 compgen을 사용하여을 사용하여 모든 명령 및 모든 별칭의 목록을 얻을 수 있습니다 compgen -ac. 별명이기도 한 모든 명령이이 목록에 복제되므로 간단한 순진 솔루션은의 출력에서 ​​중복 항목을 찾는 것입니다 compgen -ac.

그러나 명령이 경로에 두 번있는 경우 복제본이 나타날 수도 있습니다. 예를 들어, 나는이 /bin/which/usr/bin/which너무 compgen -ac나열합니다 which그것이 별칭 아니더라도 두 번.

따라서 필요한 것은 모든 복제본을 가져 와서 compgen -ac별칭 목록과 비교하는 것입니다. 별명 인 복제본 만 명령을 숨기는 별명입니다. comm(1)명령과 bash 프로세스 대체로 이를 수행 할 수 있습니다 .

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sort모든 별칭의 목록입니다 (에 대해 정렬 됨 comm). compgen -ac | sort | uniq -d명령 및 별명 목록의 모든 중복 목록입니다. comm -12둘 다 공통 인 행만 출력합니다.


5

쉘 디버깅 기능을 사용하여 bash가 대화식 쉘을 호출 할 때 발생하는 상황을 정확하게 볼 수 있습니다. 다음은 대화식 쉘이 로그인 쉘에서 생성 될 때 지정된 모든 별명을 보여줍니다.

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> 디버깅 활성화
  • -l -> 로그인 쉘
  • -i -> 대화식 쉘
  • -c -> 명령

쉘이 리턴되도록 명령 엑시트를 실행해야합니다. 은 -ibash는 달리 명령을 실행하기 위해 대화 형 환경을 설정하지 않기 때문에이 경우에 필요합니다.

내 시스템의 예는 다음과 같습니다.

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

별명을 지정했을 때 마지막으로 어떤 파일이 소스인지 확인하기 위해 파일을 판별하기 위해 grep을 확장 할 수 있습니다.

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

이는 오 탐지를 리턴 할 수 있지만 리턴 된 데이터를 수동으로 검사하는 경우에는 양호해야합니다. 실행 된 명령 앞의 '+'기호 수는 깊이를 나타냅니다.

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

이 샘플 출력에서 ​​.bashrc는 ls.foo aliases에 대한 별칭을 설정 한 t다음 .bashrc가의 이전 별칭을 재정의 함을 보여줍니다 t.


감사. 이것은 확실히 유용하지만 별칭을 만드는 충돌을 찾는 방법을 알 수는 없습니다.
user13107

@ user13107 도움이 될만한 세부 정보를 추가했습니다. 별명을 새 값으로 설정하는 것은 "충돌하는"별명이 아닙니다. 정상적인 문서화 된 동작이므로 회전 방식이 필요합니다.
jordanm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.