Bash가 전체 입력 줄을 읽은 후 해당 줄에서 명령을 실행하기 전에 결과를 표시하려면 어떻게 해야 합니까?

Bash가 전체 입력 줄을 읽은 후 해당 줄에서 명령을 실행하기 전에 결과를 표시하려면 어떻게 해야 합니까?

~에서Bash 매뉴얼, 섹션 6.6 별칭,

  …항상 슬램읽다앞에 전체 줄을 하나 이상 입력하세요. 구현하다해당 줄의 모든 명령. 명령이 실행되면 별칭이 확장됩니다.읽다, 그럴 때는 말고 처형된. 따라서 다른 명령과 같은 줄에 나타나는 별칭 정의는 다음 입력 줄을 읽을 때까지 적용되지 않습니다.

여기서 나는 이해하는 방법을 찾으려고 노력하고 있습니다. 다음 중 "입력의 전체 줄을 읽고" "해당 줄에서 명령을 실행"할 때 쉘이 수행하는 작업은 무엇입니까?

결과를 표시할 수 있는 명령과 예제가 있습니까?

  • 뒤쪽에 불다 읽다 한 줄 전체를 입력하세요.
  • 하지만앞으로 구현하다이 줄에 명령이 있나요?

예를 들어,

  • "입력의 전체 줄을 입력하십시오"는 여러 명령으로 구성된 복합 명령입니다.
  • "완전한 입력 라인"은 여러 복합 명령의 파이프라인, 파이프라인 목록 등이 될 수도 있습니다.

답변1

이를 이해하는 좋은 방법은 다음 예를 보는 것입니다.https://stackoverflow.com/questions/38526612/bash-unable-to-set-and-use-alias-in-the-same-line

예를 들어 다음 명령을 실행하려고 합니다.

$ alias foo="echo bac" ; foo;
-bash: foo: command not found
$ foo
bac

이제 bash는 전체 줄을 읽을 것이며 foo별칭이 없으므로 확장되지 않습니다(별칭은 읽을 때 확장됩니다). 이제 이 줄이 실행되면 별칭이 설정되고 오류가 발생합니다.

답변2

당신이 인용한 Bash 매뉴얼의 섹션은 다음과 같습니다.

별칭은 명령이 실행될 때가 아니라 명령을 읽을 때 확장됩니다. 따라서 다른 명령과 같은 줄에 나타나는 별칭 정의는 다음 입력 줄을 읽을 때까지 적용되지 않습니다.

따라서 앨리어싱은 실제로 줄을 읽는 것과 실행하는 것의 차이를 보여주는 예 중 하나입니다!

이를 명확히 하기 위해 복합 명령이 있습니다. 먼저 별칭을 정의한 다음 이를 사용해 봅니다.

alias echo=uname; echo

Bash에 익숙하지 않은 사람은 이 명령의 출력이 Linux(또는 실행 중인 운영 체제가 무엇이든) 것으로 예상할 수 있지만 실제로는 아무것도 출력하지 않습니다. Bash가 먼저이기 때문입니다.읽다라인을 클릭하고 별칭 정의를 적용합니다. Bash가 보는 것은 다음과 같습니다.

alias echo=uname; echo

두 번째 것은 echo로 변환되지 않습니다 uname. 이는 Bash가 alias echo=uname아직 명령을 실행하지 않았기 때문입니다.읽다그것. Bash는 해당 줄을 읽은 후 읽은 내용을 실행합니다. 따라서 다음이 실행됩니다.

alias echo=uname; echo(위에서 언급한 대로 정확히 읽혀져 있습니다)

를 입력하여 Bash가 명령을 실행했는지 확인할 수도 있습니다 echo. 이전에 별칭을 정의했으므로 이제 echo읽기 단계에서 별칭이 변환되어 Bash가 실행됩니다.unameuname

간단히 말해서:

$ alias echo=uname; echo

$ echo
Linux

편집하다:

편집, Bash가 입력 줄을 읽은 후 실제로 실행하기 전에 결과를 표시할 수 있는 방법이 있는지 물으셨습니다. 대답은 '예'입니다. 하지만 일상적인 사용에는 그다지 편리하지 않습니다(그러나 셸 내부에서 무슨 일이 일어나고 있는지 이해하는 데는 확실히 유용합니다).

다음 내용으로 파일을 만듭니다.

#!/bin/bash
shopt -s expand_aliases
trapped() {
    echo "On line ${1}, Bash sees: $BASH_COMMAND"
}
trap 'trapped ${LINENO}' DEBUG
alias echo=uname; echo
echo

그런 다음 파일을 실행하십시오.

다음은 스크립트 작동 방식에 대한 설명입니다.

  • shopt -s expand_aliases비대화형 모드인 경우에도 별칭을 확장하도록 Bash에 지시합니다(이 예와 같이).
  • 그런 다음 함수를 정의합니다 trapped(). 호출되면 이 함수는 현재 실행 중인 명령을 (인수로 전달된 줄 번호와 함께) 인쇄합니다.
  • 우리는 그것을 이라고 부릅니다 trap 'trapped ${LINENO}' DEBUG. 이는 Bash에게 "라는 신호를 볼 때마다 DEBUG먼저 trapped ${LINENO}실행하십시오. DEBUG이것은 Bash가 자동으로 생성한 신호입니다.간단한 명령을 실행하기 전에. 즉, trapped()명령이 실행되기 전에 함수가 호출됩니다.
  • 마지막으로 데모를 위해 몇 가지 명령을 실행합니다. 그러나 다른 일이 일어나기 전에 실행되는 트랩이 있으므로 trapped()Bash는 곧 실행될 내용을 인쇄합니다. 이 LINENO변수는 현재 줄 번호를 제공하는 Bash 내장 변수입니다.

명령을 실행하지 않고 "실행"하고 Bash가 읽는 내용을 계속 보려면 extdebugBash 매뉴얼의 옵션을 살펴보는 것이 좋습니다.

답변3

귀하의 질문은 매우 명확하지 않지만 귀하의 문장의 병치는

주문할 때읽다, 그럴 때는 말고처형된.

그리고

항상 꽝 닫아읽다앞에 전체 줄을 하나 이상 입력하세요. 구현하다해당 줄의 모든 명령.

질문의 초점이 별칭 확장임을 나타냅니다. (Bash 매뉴얼 발췌 부분을 제외하고 귀하의 질문에 별칭이 전혀 언급되지 않았기 때문에 "제안"이라고 말합니다.)

질문의 원본 버전

Bash가 해당 줄에서 명령을 실행하기 전에 항상 입력의 전체 줄을 읽는다는 것을 어떻게 증명할 수 있습니까?

이를 수행하는 유일한 실제 방법은 일종의 디버깅/모니터링/추적 도구를 사용하여 셸의 내부 상태를 검사하는 것입니다. 이것은 약간 비현실적입니다.  꼬마 펭귄의 대답수동 인수를 통해 수동 콘텐츠를 지원하는 방법을 보여줍니다. 다음은 (IMO) 좀 더 명확한 답변의 변형입니다.

$ 별칭 myalias=날짜

$ 별칭 myalias="ls -ld";
2017년 8월 4일 금요일 오전 3:33:33

쉘이 실행을 시작하기 전에 (두 번째) 전체 라인을 완전히 읽어야 한다고 말할 수 있습니다. 왜냐하면 쉘이 실행될 때 다음 과 같이 myalias실행되기 때문입니다. 별칭이 실행 date되면 으로 재정의되므로 셸이 다음으로 확장되어야 합니다.myaliasls -ldmyaliasdate

alias myalias="ls -ld"

명령이므로 해당 줄에서 명령을 실행하기 전에 전체 입력 줄을 읽어야 합니다.


귀하의 수정된 질문,

Bash가 전체 입력 줄을 읽은 후 해당 줄에서 명령을 실행하기 전에 결과를 표시하려면 어떻게 해야 합니까?

이 경우에는 더 의미가 있습니다. 명령줄을 보고 싶은 것 같아요별칭 확장됨  해당 줄에서 명령을 실행하기 전, 즉 별칭 확장 결과를 확인합니다. 내 생각엔 당신이 다음과 같은 것을 보고 싶어하는 것 같아요

alias myalias="ls -ld"; date

내가 아는 한, 해당 출력을 얻을 수 있는 방법은 없습니다. 별칭이 확장된 전체 줄입니다. 그러나 xtrace( -x) 옵션은 가깝습니다.

$세트-x

$ 별칭 myalias=날짜
+ 별칭 myalias=날짜

$ 별칭 myalias="ls -ld";
+ 별칭 'myalias=ls -ld'
+ 날짜                                                         ← 별칭 확장
2017년 8월 4일 금요일 오전 3:33:42

물론 이는 확장된 각 명령이 실행되기 전에만 출력하므로 별칭 확장의 결과가 명령의 출력과 혼합됩니다. 추가적으로 이는 다음과 같이 나타납니다.모두확장:

$animal=고양이
+ 동물 = 고양이

$echo 안녕하세요, myalias "$animal" R*
+ 에코 안녕하세요
안녕하세요
+ 세상에 반향을 일으키다
세계
+ ls -ld cat 추가 정보 파일                                            ← 별칭 확장
ls: 접근할 수 없습니다. cat: 해당 파일이나 디렉터리가 없습니다.
-rw-r--r-- 2내 사용자 이름 내 그룹 이름  489 2015년 2월 22일 읽어보기

우리는 그것을 볼 수 없습니다 ls -ld "$animal" R*. 변수 확장과 경로 이름(glob) 확장 후에만 볼 수 있습니다. 또한 파이프에서는 "잘 작동"하지 않습니다.

$ 별칭 myalias=날짜
+ 별칭 myalias=날짜

$ 별칭 |
+ 날짜                                                         ← 별칭 확장
+od-cb
0000000 8월 04, 2 0 1 금요일
        106 162 151 054 040 101 165 147 040 060 064 054 040 062 060 061
0000020 7 9 : 4 2 : 1 오후 7시\n
        067 040 040 071 072 064 062 072 061 067 040 120 115 012
0000036

추적 출력은 date두 개의 개별 라인에 합계를 표시합니다. (출력에서 알 수 없는 경우 od -cb원래 명령줄을 보고 그것이 수행 중인 작업을 파악해야 합니다.)date | od -cb

관련 정보