bash에서 마지막 출력 줄을 어떻게 실행할 수 있습니까? 있습니다. The program ‘git’ is currently not installed.

bash에서 마지막 명령을 실행할 수 있다는 것을 알고 !!있지만 마지막 출력 줄을 어떻게 실행할 수 있습니까?

이 출력의 유스 케이스를 생각하고 있습니다.

The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

그러나 나는 그것을 어떻게 실행할 수 있는지 모른다. !!어쩌면 @@비슷한 비슷한 것을 생각하고 있습니까?


슈퍼 유저도이 질문을 가지고 있습니다.



답변

명령 $(!! |& tail -1)은 다음을 수행해야합니다.

$ git something
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git

$ $(!! |& tail -1)
$(git something |& tail -1)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
git-man liberror-perl

보시다시피 sudo apt-get install git명령이 실행 중입니다.

편집 : 세분화$(!! |& tail -1)

  • $()는 IS bash명령 치환 패턴

  • bash!!마지막으로 실행 된 명령으로 확장 됩니다

  • |&부분은 까다 롭습니다. 일반적으로 파이프 |는 왼쪽 명령의 STDOUT을 가져 와서 오른쪽의 명령에 STDIN으로 전달 |합니다.이 경우 이전 명령은 STDERR에 출력을 오류 메시지로 인쇄합니다. 따라서 |도움이되지 않으면 STDOUT 및 STDERR (또는 STDERR 만)을 오른쪽 명령으로 전달해야합니다. |&STDIN으로 STDOUT과 STDERR을 모두 오른쪽 명령에 전달합니다. 또는 STDERR 만 전달하는 것이 좋습니다.

    $(!! 2>&1 >/dev/null | tail -1)
  • tail -1평소와 같이 입력에서 마지막 줄을 인쇄합니다. 마지막 줄을 인쇄하는 대신 apt-get install명령 이 포함 된 줄을 인쇄하는 것보다 더 정확할 수 있습니다 .

    $(!! 2>&1 >/dev/null | grep 'apt-get install')

답변

TL; DR : alias @@='$($(fc -ln -1) |& tail -1)'

Bash의 히스토리 상호 작용 기능 은 명령 의 출력 을 검사하는 메커니즘을 제공하지 않습니다 . 쉘은 저장하지 않으며 , 히스토리 확장은 특별히 실행 한 명령 또는 해당 명령의 일부를위한 것입니다.

이로써 마지막 명령을 다시 실행하고 stdoutstderr ( |&)를 명령 대체로 파이프하는 방법이 남습니다 . heemayl의 대답은 이것을 달성하지만 셸은 별칭을 확장하기 전에 히스토리 확장을 수행하기 때문에 별칭을 사용할 수 없습니다.

로 함수에서 활성화하더라도 쉘 함수에서 히스토리 확장을 작동시킬 수 없습니다 set -H. 나는 !!함수가 확장되지 않을 것이라고 의심 하고, 그것이 확장되었을 때 확장 될지 확실하지 않지만, 지금 그것이 확장되지 않았는지 정확히 모르겠습니다 .

따라서 아주 적은 타이핑으로이를 수행 할 수 있도록 설정하려면 히스토리 확장 대신 fc쉘 내장을 사용하여 히스토리에서 마지막 명령을 추출해야합니다. 이것은 기록 확장이 비활성화 된 경우에도 작동한다는 추가 이점이 있습니다.

에 나타낸 바와 같이 고든 데이비슨대답bash는 역사 확장을 포함하는 별칭 만들기 (에 슈퍼 사용자 ) $(fc -ln -1)을 시뮬레이션을 !!. heemayl의 명령!! 에 이것을 연결 하면 다음과 같습니다. $(!! |& tail -1)

$($(fc -ln -1) |& tail -1)

이것은 작동 $(!! |& tail -1)하지만 별칭 정의로 갈 수 있습니다.

alias @@='$($(fc -ln -1) |& tail -1)'

해당 정의를 실행하거나 새 셸 에 .bash_aliases넣거나 .bashrc새 셸을 시작한 @@후 마지막 명령에서 마지막 출력 줄을 실행하기 위해 간단히 입력 (또는 별명이라는 이름을 지정할 수 있음) 할 수 있습니다 .

ek@Io:~$ alias @@='$($(fc -ln -1) |& tail -1)'
ek@Io:~$ evolution
The program 'evolution' is currently not installed. You can install it by typing:
sudo apt-get install evolution
ek@Io:~$ @@
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  evolution-common evolution-data-server evolution-data-server-online-accounts
....

답변

당신이 X에서 터미널 에뮬레이터를 사용하는 경우와 같은 gnome-terminal, konsole또는 xterm, 당신은 복사 및 붙여 넣기 같은 것을 위해 X 선택을 사용할 수 있습니다 :

기본 선택 사용

왼쪽 세 번 클릭 으로 실행할 전체 줄 을 선택 하십시오 .

그런 다음 가운데 버튼을 클릭 하여 명령 줄에 붙여 넣습니다 .

이것은 대부분의 터미널 에뮬레이터에서 작동합니다. 클립 보드를 건드리지 않고 기본 선택을 사용합니다. 별도입니다.
기술적으로 선택하여 한 번의 작업으로 복사 및 붙여 넣기를 결합했습니다.


답변

Eliah Kagan이 언급했듯이 셸은 명령 출력을 저장하지 않습니다. 그러나, 출력의 마지막 명령의 마지막 줄을 얻을 수있는 방법이 명령을 다시 실행하지 않고 실행할 경우, 화면 .

다음 줄을 입력하십시오 ~/.screenrc.

register t "^a[k0y$ ^a]^a^L"
bind t process t

그런 다음 Ctrl+ at를 눌러 현재 프롬프트에 이전 줄을 삽입 할 수 있습니다 . Enter 키를 자동으로 누르는 것도 가능하지만 실행하기 전에 확인하고 Enter 키를 누르는 것이 좋습니다.

작동 방식 :

  • register t이라는 이름의 버퍼에 문자열을 등록합니다 t. 그 뒤에 나오는 문자열은 키 순서입니다.
  • bind t키에 바인딩합니다 t(즉 , Ctrl+를 사용하여 실행 at) . process t라는 버퍼의 내용을 평가하는 것을 의미합니다 t.
  • 시퀀스 자체는 다음을 의미합니다.
    • ^a[(= Ctrla[) : 복사 모드로 들어갑니다
    • k한 줄 위로 0이동, 줄 시작으로 이동, 줄 y$끝까지 복사, (공백) 명령 완료
    • ^a](= Ctrla]) : 복사 한 내용 붙여 넣기
    • ^a^L(= CtrlaCtrlL) 화면을 새로 고칩니다 (그렇지 않으면 직접 입력하지 않았기 때문에 붙여 넣은 내용이 표시되지 않습니다