programing

Bash를 사용하여 마지막 명령어의 출력을 자동으로 변수에 캡처하시겠습니까?

instargram 2023. 4. 17. 21:17
반응형

Bash를 사용하여 마지막 명령어의 출력을 자동으로 변수에 캡처하시겠습니까?

마지막으로 실행한 명령어의 결과를 후속 명령어로 사용할 수 있도록 하고 싶습니다.예를들면,

$ find . -name foo.txt
./home/user/some/directory/foo.txt

이제 편집기에서 파일을 열거나 삭제하거나 다른 작업을 수행할 수 있습니다.

mv <some-variable-that-contains-the-result> /some/new/location

어떻게 해야 하죠?배쉬 변수라도 쓸까?

업데이트:

확실히 하자면, 수동으로 할당하는 것은 싫습니다.제가 찾고 있는 것은 내장 bash 변수와 같은 것입니다.

ls /tmp
cd $_

$_에는 이전 명령어의 마지막 인수가 포함됩니다.마지막 명령어 출력과 비슷한 것을 원합니다.

최종 갱신:

세스의 대답은 꽤 효과가 있었다.유의해야 할 몇 가지 사항:

  • 말고 꼭 해 주세요touch /tmp/x을 처음 할 때
  • 마지막 명령의 종료 코드가 성공한 경우에만 결과가 저장됩니다.

기능을 자동으로 수행하는 변수는 없습니다.결과 복사 붙여넣기 외에도 방금 실행한 작업을 다시 실행할 수 있습니다.

vim $(!!)

서 ★★★★★!!는 '이전 명령어'를 의미하는 이력 확장입니다.

해석을수 공백이나 된 단일 파일 이 있을 결과 「」 「」 「」 「」 「」 「」 「」 「」 「」 「1」 「」 「」)를 합니다.vim "$(!!)"따옴표로 묶지 않은 채로 두면 공백이나 다른 셸 해석 토큰이 포함되지 않는 한 여러 파일을 동시에 열 수 있습니다.

이것은 매우 진부한 해결책이지만, 대부분의 경우 효과가 있는 것 같습니다.테스트 중에 커맨드 라인에 접속할 때 잘 작동하지 않는 경우가 있다는 것을 알게 되었습니다.다만, 조금 더 잘 동작하도록 조정했습니다.

이 해킹은 인터랙티브 모드 해킹일 뿐이므로 누구에게도 추천하지 않을 자신이 있습니다.background 명령어는 통상보다 정의되어 있지 않은 동작을 일으킬 가능성이 있습니다.다른 답변은 프로그래밍 방식으로 결과를 얻는 더 나은 방법입니다.


「솔루션」은 다음과 같습니다.

PROMPT_COMMAND='LAST="`cat /tmp/x`"; exec >/dev/tty; exec > >(tee /tmp/x)'

이 bash 환경변수를 설정하고 필요에 따라 명령을 발행합니다. $LAST에는 보통 . 즉,통, 음, 음, 음, 음, 음, 음, 음, 음, 음, 음, will, will, will, will, will, will will,

startide seth> fortune
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve
startide seth> echo "$LAST"
Courtship to marriage, as a very witty prologue to a very dull play.
                -- William Congreve

Bash는 좀 추악한 언어예요.예, 출력을 변수에 할당할 수 있습니다.

MY_VAR="$(find -name foo.txt)"
echo "$MY_VAR"

하하최하find하나의 결과만 반환하고 그 결과에는 캐리지 리턴이나 줄 바꿈과 같은 "홀수" 문자가 포함되지 않았습니다.배쉬하다

그러나 변수를 사용할 때 올바른 인용을 하도록 주의해야 합니다.

은 직접하는 것이 예를 '을 사용하는 것이 좋습니다.★★★★★★★★★★★★★★★★★,find의 »-execdir(일부러)

find -name foo.txt -execdir vim '{}' ';'

또는

find -name foo.txt -execdir rename 's/\.txt$/.xml/' '{}' ';'

여기에는 여러 가지 방법이 있습니다. 가지 은 '우리'를 사용하는 입니다.v=$(command)은 「명령어 출력」에 됩니다.v §:

v=$(date)
echo $v

그리고 백인테이트도 사용할 수 있습니다.

v=`date`
echo $v

Bash 초보자 가이드에서

이전 형식의 백따옴표 형식의 치환을 사용할 경우 백슬래시는 "$", "'" 또는 "\" 뒤에 이어지는 경우를 제외하고 문자 그대로의 의미를 유지합니다.백슬래시가 선행되지 않은 첫 번째 백틱은 명령어 대체를 종료합니다."$(COMMAND)" 형식을 사용할 경우 괄호 사이의 모든 문자가 명령을 구성합니다. 특별히 처리되는 문자는 없습니다.

편집: 질문 편집 후 OP가 원하는 것은 이것이 아닌 것 같습니다.가 없는 으로 알고 있습니다.$_마지막 명령어 출력에 사용합니다.

꽤 쉬워요.따옴표 사용:

var=`find . -name foo.txt`

그리고 당신은 미래에 언제든지 그것을 사용할 수 있습니다.

echo $var
mv $var /somewhere

디스카머:

  • 이 답변은 반년 후입니다.D
  • 헤비 tmux 사용자입니다.
  • 이 기능이 작동하려면 tmux에서 셸을 실행해야 합니다.

tmux에서 인터랙티브 셸을 실행하면 단말기에 현재 표시된 데이터에 쉽게 액세스할 수 있습니다.다음으로 몇 가지 흥미로운 명령어를 살펴보겠습니다.

  • tmux capture-buffer: 표시된 데이터를 tmux의 내부 버퍼 중 하나에 복사합니다.현재 보이지 않는 이력을 복사할 수 있지만 지금은 관심이 없습니다.
  • tmux list-buffer: 캡처된 버퍼에 대한 정보를 표시합니다.가장 최근의 것은 숫자 0이 될 것이다.
  • tmux show-display - b (syslog num): 지정된 버퍼의 내용을 단말기에 출력합니다.
  • tmux paste-flash -b (flash num): 지정된 버퍼의 내용을 입력으로 붙여넣습니다.

이 생기게 : ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ) ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄴ.alias L="tmux capture-pane; tmux showb -b 0 | tail -n 3 | head -n 1"해야 할 '마지막 줄'을 사용합니다.$(L)얻을 수 있습니다.

이것은 프로그램이 사용하는 출력 스트림(stdin 또는 stderr), 인쇄 방법(ncurses 등), 프로그램의 종료 코드와는 무관합니다.데이터만 표시하면 됩니다.

다음 내용을 포함하는 스크립트에 셸을 설정하는 솔루션을 해킹할 수 있을 것 같습니다.

#!/bin/sh
bash | tee /var/log/bash.out.log

으로, 「」를 했을 경우는, 「」를 설정합니다.$PROMPT_COMMAND하려면 , 함수( 「도움말」이라고 )를 쓸 수 ._덩어리를 같이 할 수

% find lots*of*files
...
% echo "$(_)"
... # same output, but doesn't run the command again

bash 프로파일로 다음 에일리어스를 설정할 수 있습니다.

alias s='it=$($(history | tail -2 | head -1 | cut -d" " -f4-))'

그런 다음 임의 명령 뒤에 's'를 입력하여 셸 변수 'it'에 결과를 저장할 수 있습니다.

예를 들어 다음과 같습니다.

$ which python
/usr/bin/python
$ s
$ file $it
/usr/bin/python: symbolic link to `python2.6'

백틱을 사용하여 출력을 캡처합니다.

output=`program arguments`
echo $output
emacs $output

는 이것을 했다.bash하다

grab() {     
  grab=$("$@")
  echo $grab
}

그러면 다음 작업을 수행합니다.

> grab date
Do 16. Feb 13:05:04 CET 2012
> echo $grab
Do 16. Feb 13:05:04 CET 2012

업데이트: 익명 사용자가 바꾸기를 제안했습니다.echo타타에 printf '%s\n'은 '하다, 하다, 하다, 하다'와 같은 장점이 있습니다.-e캡처된 텍스트에 있습니다.그래서 만약 당신이 그러한 특이점을 기대하거나 경험한다면, 이 제안을 고려해보세요. 하나의 은 ' 낫다'를 하는 것입니다.cat <<<$grab★★★★★★ 。

마지막으로 실행된 명령어의 결과를 후속 명령어로 사용할 수 있으면 좋겠다고 말하는 것은 단순히 찾는 것이 아니라 모든 명령어의 결과를 의미한다고 생각합니다.

만약 그렇다면 - xargs가 당신이 찾고 있는 것입니다.

find . -name foo.txt -print0 | xargs -0 -I{} mv {} /some/new/location/{}

또는 먼저 출력을 확인하는 경우:

find . -name foo.txt -print0

!! | xargs -0 -I{} mv {} /some/new/location/{}

이 명령어는 여러 파일을 처리하며 경로 및/또는 파일 이름에 공백이 포함되어 있는 경우에도 매력적으로 작동합니다.

명령어의 mv {} /some/new/location/{} 부분에 주의하십시오.이 명령어는 이전 명령어로 출력된 각 행에 대해 작성 및 실행됩니다.여기서는 이전 명령으로 인쇄된 행이 {} 대신 교체됩니다.

xargs의 man 페이지에서 발췌:

xargs - 표준 입력에서 명령줄을 만들고 실행합니다.

한 것에 대하여는, 페이지: 「Man」을 참조해 주세요.man xargs

나는 보통 여기 다른 사람들이 제안한 대로 한다... 임무 없이:

$find . -iname '*.cpp' -print
./foo.cpp
./bar.cpp
$vi `!!`
2 files to edit

원하는 경우 더 고급스러운 기능을 사용할 수 있습니다.

$grep -R "some variable" * | grep -v tags
./foo/bar/xxx
./bar/foo/yyy
$vi `!!`

마지막 명령어를 재실행하여 출력을 얻는 것이 목적이라면 간단한 bash 변수가 작동합니다.

LAST=`!!`

그러면 다음 명령을 출력에 대해 실행할 수 있습니다.

yourCommand $LAST

그러면 새로운 프로세스가 생성되고 명령어가 다시 실행되어 출력이 나타납니다.명령어 출력용 bash 이력 파일이 필요한 것 같습니다.즉, bash가 단말기에 송신하는 출력을 캡처해야 합니다.필요한 /dev 또는 /proc를 보기 위해 무언가를 쓸 수 있지만, 그것은 지저분합니다.중간에 tee 명령을 사용하여 용어와 bash 사이에 "특수 파이프"를 생성하여 출력 파일로 리디렉션할 수도 있습니다.

하지만 그 둘 다 일종의 해답이다.가장 좋은 것은 출력 로깅 기능이 있는 보다 현대적인 터미널인 터미네이터라고 생각합니다.마지막 명령어 결과에 대해서는 로그 파일을 확인하십시오.위와 유사한 bash 변수를 사용하면 이 작업이 더욱 쉬워집니다.

다음은 명령을 실행하고 결과를 변수에 저장하기로 결정한 후 수행하는 한 가지 방법입니다.

$ find . -name foo.txt
./home/user/some/directory/foo.txt
$ OUTPUT=`!!`
$ echo $OUTPUT
./home/user/some/directory/foo.txt
$ mv $OUTPUT somewhere/else/

또는 결과를 변수에 포함시킬지 미리 알고 있는 경우 backticks를 사용할 수 있습니다.

$ OUTPUT=`find . -name foo.txt`
$ echo $OUTPUT
./home/user/some/directory/foo.txt

기존 답변에 대한 대안으로 다음과 같은 것이 있습니다.while파일 이름에 다음과 같은 공백이 포함될 수 있는 경우:

find . -name foo.txt | while IFS= read -r var; do
  echo "$var"
done

제가 쓴 것처럼 파일 이름에 공백이 있을 경우에만 차이가 있습니다.

NB: 유일하게 내장된 내용은 출력이 아니라 마지막 명령어 상태에 관한 것입니다.

!:1 을 사용할 수 있습니다.예:

~]$ ls *.~
class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 

~]$ rm !!:1
rm class1.cpp~ class1.h~ main.cpp~ CMakeList.txt~ 


~]$ ls file_to_remove1 file_to_remove2
file_to_remove1 file_to_remove2

~]$ rm !!:1
rm file_to_remove1

~]$ rm !!:2
rm file_to_remove2

저도 비슷한 요구가 있어서 마지막 명령어의 출력을 다음 명령어에 사용하고 싶었습니다.|(파이프)와 비슷합니다.

$ which gradle 
/usr/bin/gradle
$ ls -alrt /usr/bin/gradle

예를 들면...

$ which gradle |: ls -altr {}

해결 방법 : 이 사용자 지정 파이프를 만들었습니다.xargs를 사용하는 것은 매우 간단합니다.

$ alias :='xargs -I{}'

기본적으로 Xargs를 위한 짧은 손을 만드는 것만으로 아무것도 할 수 없고, 매력적이고, 매우 편리합니다.에일리어스를 .bash_profile 파일에 추가합니다.

및 기술자의 할 수 .lastpipe셸 옵션

이 작업은 스크립트를 사용하여 수행해야 합니다. "라스트파이프" 옵션은 대화형 모드에서 작동하지 않습니다.

테스트한 스크립트는 다음과 같습니다.

$ cat shorttest.sh 
#!/bin/bash
shopt -s lastpipe

exit_tests() {
    EXITMSG="$(cat /proc/self/fd/0)"
}

ls /bloop 2>&1 | exit_tests

echo "My output is \"$EXITMSG\""


$ bash shorttest.sh 
My output is "ls: cannot access '/bloop': No such file or directory"

내가 여기서 하는 일은:

  1. , 셸 옵션 " " " "shopt -s lastpipe. 기술자를 이하지 않습니다 파일 기술자를 잃어버리기 때문에 이 기능이 없으면 작동하지 않습니다.

  2. .2>&1

  3. stdin 파일 설명자를 참조할 수 있도록 출력을 함수에 연결합니다.

  4. , " "의 내용을 ./proc/self/fd/0스틴

스크립트에서 오류를 캡처하기 위해 사용하고 있기 때문에 명령어에 문제가 있을 경우 스크립트 처리를 중지하고 바로 종료할 수 있습니다.

shopt -s lastpipe

exit_tests() {
    MYSTUFF="$(cat /proc/self/fd/0)"
    BADLINE=$BASH_LINENO
}

error_msg () {
    echo -e "$0: line $BADLINE\n\t $MYSTUFF"
    exit 1
}

ls /bloop 2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg

해서 제가 더하면 요.2>&1 | exit_tests ; [[ "${PIPESTATUS[0]}" == "0" ]] || error_msg가가확확확확확은은뒤뒤뒤뒤뒤뒤뒤뒤뒤 。

이제 출력을 즐기실 수 있습니다!

이는 엄밀하게 bash 솔루션은 아니지만 sed와 함께 파이프를 사용하여 이전 명령어의 마지막 행을 출력할 수 있습니다.

먼저 폴더 "a"에 무엇이 있는지 확인합니다.

rasjani@helruo-dhcp022206::~$ find a
a
a/foo
a/bar
a/bat
a/baz
rasjani@helruo-dhcp022206::~$ 

다음으로 ls와 cd의 예에서는 sed와 piping이 다음과 같이 됩니다.

rasjani@helruo-dhcp022206::~$ cd `find a |sed '$!d'`
rasjani@helruo-dhcp022206::~/a/baz$ pwd
/home/rasjani/a/baz
rasjani@helruo-dhcp022206::~/a/baz$

sed에서 실제 마법이 일어납니다. 명령어 출력의 어떤 것이든 sed와 sed 프린트에 파이프로 연결하여 뒷눈금을 파라미터로 사용할 수 있습니다.또는 xargs와 결합할 수도 있습니다.("shell의 man xargs는 당신의 친구입니다")

셸에는 마지막 명령어의 에코 결과를 저장하는 perl과 같은 특수 기호가 없습니다.

파이프 기호를 awk와 함께 사용하는 방법을 배웁니다.

find . | awk '{ print "FILE:" $0 }'

위의 예에서는 다음을 수행할 수 있습니다.

find . -name "foo.txt" | awk '{ print "mv "$0" ~/bar/" | "sh" }'
find . -name foo.txt 1> tmpfile && mv `cat tmpfile` /path/to/some/dir/

더럽긴 하지만 또 다른 방법입니다.

은, 「이러한 파일」에 .솔루션의 기능은.bash_profile파일 내의 출력을 캡처하여 필요할 때 결과를 반환합니다.

은 명령어를 다시 입니다.find또는 중요할 수 있는 기타 장시간 실행 명령어)

이걸 됩니다..bash_profile

대본

# catch stdin, pipe it to stdout and save to a file
catch () { cat - | tee /tmp/catch.out}
# print whatever output was saved to a file
res () { cat /tmp/catch.out }

사용.

$ find . -name 'filename' | catch
/path/to/filename

$ res
/path/to/filename

되면 이에요.| catch모든 명령어를 끝까지 실행할 수 있습니다.비용이 들지 않고 완료까지 시간이 오래 걸리는 명령어를 재실행할 필요가 없기 때문입니다.

또한 텍스트 편집기에서 파일 출력을 열려면 다음을 수행할 수 있습니다.

# vim or whatever your favorite text editor is
$ vim <(res)

언급URL : https://stackoverflow.com/questions/5955577/automatically-capture-output-of-last-command-into-a-variable-using-bash

반응형