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)
-
$()
는 ISbash
명령 치환 패턴 -
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의 히스토리 상호 작용 기능 은 명령 의 출력 을 검사하는 메커니즘을 제공하지 않습니다 . 쉘은 저장하지 않으며 , 히스토리 확장은 특별히 실행 한 명령 또는 해당 명령의 일부를위한 것입니다.
이로써 마지막 명령을 다시 실행하고 stdout 및 stderr ( |&
)를 명령 대체로 파이프하는 방법이 남습니다 . 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) 화면을 새로 고칩니다 (그렇지 않으면 직접 입력하지 않았기 때문에 붙여 넣은 내용이 표시되지 않습니다