Bash의 마지막 명령어 출력 재사용
Bash 명 bash bash bash e e e e e? 를음음음음음음음음음음 to to to to to to to to to to $?종료 상태가 아닌 출력을 캡처합니다.
다음과 같은 방법으로 출력을 변수에 할당할 수 있습니다.
output=$(command)
하지만 그건 타이핑이 더...
하시면 됩니다.$(!!)마지막 명령어의 출력을 재계산(재사용하지 않음)합니다.
!!는 그 자체로 마지막 명령을 실행합니다.
$ echo pierre
pierre
$ echo my name is $(!!)
echo my name is $(echo pierre)
my name is pierre
대답은 '아니오'입니다.Bash는 메모리 상의 파라미터나 블록에 출력을 할당하지 않습니다.또한 허용된 인터페이스 조작에 의해서만 Bash에 액세스할 수 있습니다.Bash의 개인 데이터는 해킹하지 않으면 접근할 수 없습니다.
매우 심플한 솔루션
내가 몇 년 동안 써온 거야
에 ).bashrc ★★★★★★★★★★★★★★★★★」.bash_profile)
# capture the output of a command so it can be retrieved with ret
cap () { tee /tmp/capture.out; }
# return the output of the most recent command that was captured by cap
ret () { cat /tmp/capture.out; }
사용.
$ find . -name 'filename' | cap
/path/to/filename
$ ret
/path/to/filename
는 원래 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ.| cap아! 저속 텍스트 했을 때 든지 " "로 수 .ret.
mac에서 변수에 쓰는 대신 클립보드에 출력을 저장하는 것이 문제가 되지 않는 경우 pbcopy와 pbpaste를 회피책으로 사용할 수 있습니다.
예를 들어, 파일을 검색하여 다른 파일로 내용을 구분하는 대신 다음을 수행합니다.
$ find app -name 'one.php'
/var/bar/app/one.php
$ diff /var/bar/app/one.php /var/bar/two.php
다음과 같이 할 수 있습니다.
$ find app -name 'one.php' | pbcopy
$ diff $(pbpaste) /var/bar/two.php
" " "/var/bar/app/one.php첫 번째 명령을 실행할 때 클립보드에 있습니다.
그나저나, pb inpbcopy ★★★★★★★★★★★★★★★★★」pbpaste클립보드의 동의어인 페이스트보드를 나타냅니다.
그 중는 '아예'를 입니다.trap DEBUG:
f() { bash -c "$BASH_COMMAND" >& /tmp/out.log; }
trap 'f' DEBUG
및 은 stdout stderr에서 사용할 수 ./tmp/out.log
, 2회 하는 것이 를 2회 경우는 입니다./tmp/out.log을 사용하다아마 이런 행동을 막을 수 있는 방법이 있을 거예요.
anubhava의 답변에서 영감을 얻어 각 명령어를 두 번 실행하므로 실제로는 받아들일 수 없다고 생각합니다.
save_output() {
exec 1>&3
{ [ -f /tmp/current ] && mv /tmp/current /tmp/last; }
exec > >(tee /tmp/current)
}
exec 3>&1
trap save_output DEBUG
이렇게 하면 last 명령어의 출력은 /tmp/last이며 명령어는 두 번 호출되지 않습니다.
그래, 왜 매번 여분의 줄을 쳐야 하지? 동의해.명령에서 반환된 를 파이프라인에 의한 입력으로 리다이렉트 할 수 있지만 인쇄 출력을 입력(1>&0)으로 리다이렉트 하는 것은 적어도 여러 줄 출력에서는 할 수 없습니다.또한 동일한 파일에 대해 함수를 여러 번 다시 쓰는 것도 원하지 않을 것입니다.그럼 다른 걸 해보죠
간단한 회피책은 printf 함수를 사용하여 변수에 값을 저장하는 것입니다.
printf -v myoutput "`cmd`"
예를 들어
printf -v var "`echo ok;
echo fine;
echo thankyou`"
echo "$var" # don't forget the backquotes and quotes in either command.
커스터마이즈 가능한 또 다른 범용 솔루션(나 자신이 사용)에서는 원하는 명령어를 한 번만 실행하여 어레이 변수에서 한 줄씩 여러 줄 출력할 수 있습니다.
파일을 내보내지 않고 로컬에서만 사용하려는 경우 터미널에서 함수 선언을 설정할 수 있습니다. You have to add the function in 에 기능을 추가해야 합니다.~/.bashrc file or in 줄서기 또는 줄서기 또는 줄서기~/.profile파일. 둘째 경우 일을 사용하도록 설정해야 합니다. 두 번째 경우,Run command as login shell부에서Edit>Preferences>yourProfile>Command.
다음과 같이 간단한 함수를 만듭니다.
get_prev() # preferably pass the commands in quotes. Single commands might still work without.
{
# option 1: create an executable with the command(s) and run it
#echo $* > /tmp/exe
#bash /tmp/exe > /tmp/out
# option 2: if your command is single command (no-pipe, no semi-colons), still it may not run correct in some exceptions.
#echo `"$*"` > /tmp/out
# option 3: (I actually used below)
eval "$*" > /tmp/out # or simply "$*" > /tmp/out
# return the command(s) outputs line by line
IFS=$(echo -en "\n\b")
arr=()
exec 3</tmp/out
while read -u 3 -r line
do
arr+=($line)
echo $line
done
exec 3<&-
}
그래서 1에 있는 것은 임시 파일 션 1 1 령 체 시 일에 1 was so did what다 option니 command인 in file we the습파임했 to a전쇄로를명 print어/tmp/exe and run it and save the output to another file 실행 후 출력을 다른 파일에 저장합니다./tmp/out 이 글의 ./tmp/out아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 네.실행할 실행 파일에 쓰지 않고 명령어를 그대로 내보낸다는 점만 제외하면 옵션2와 3과 비슷합니다.
기본 스크립트:
#run your command:
cmd="echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
get_prev $cmd
#or simply
get_prev "echo hey ya; echo hey hi; printf `expr 10 + 10`'\n' ; printf $((10 + 20))'\n'"
하므로 bash는 이전 범위를 벗어나도 합니다.arr에서 get_prev메인 스크립트의 기능 외부에서도 기능에 액세스 할 수 있습니다.
#get previous command outputs in arr
for((i=0; i<${#arr[@]}; i++))
do
echo ${arr[i]}
done
#if you're sure that your output won't have escape sequences you bother about, you may simply print the array
printf "${arr[*]}\n"
편집:
I use the following code in my implementation:get_prev()
{
usage()
{
echo "Usage: alphabet [ -h | --help ]
[ -s | --sep SEP ]
[ -v | --var VAR ] \"command\""
}
ARGS=$(getopt -a -n alphabet -o hs:v: --long help,sep:,var: -- "$@")
if [ $? -ne 0 ]; then usage; return 2; fi
eval set -- $ARGS
local var="arr"
IFS=$(echo -en '\n\b')
for arg in $*
do
case $arg in
-h|--help)
usage
echo " -h, --help : opens this help"
echo " -s, --sep : specify the separator, newline by default"
echo " -v, --var : variable name to put result into, arr by default"
echo " command : command to execute. Enclose in quotes if multiple lines or pipelines are used."
shift
return 0
;;
-s|--sep)
shift
IFS=$(echo -en $1)
shift
;;
-v|--var)
shift
var=$1
shift
;;
-|--)
shift
;;
*)
cmd=$option
;;
esac
done
if [ ${#} -eq 0 ]; then usage; return 1; fi
ERROR=$( { eval "$*" > /tmp/out; } 2>&1 )
if [ $ERROR ]; then echo $ERROR; return 1; fi
local a=()
exec 3</tmp/out
while read -u 3 -r line
do
a+=($line)
done
exec 3<&-
eval $var=\(\${a[@]}\)
print_arr $var # comment this to suppress output
}
print()
{
eval echo \${$1[@]}
}
print_arr()
{
eval printf "%s\\\n" "\${$1[@]}"
}
다중/파이프라인/두 명령어의 공백으로 구분된 출력을 줄 구분된 출력으로 인쇄하기 위해 이 기능을 사용해 왔습니다.
get_prev -s " " -v myarr "cmd1 | cmd2; cmd3 | cmd4"
예를 들어 다음과 같습니다.
get_prev -s ' ' -v myarr whereis python # or "whereis python"
# can also be achieved (in this case) by
whereis python | tr ' ' '\n'
, 이제tr는 다른합니다.
echo $PATH | tr ':' '\n'
그러나 다중/피핑된 명령의 경우...이제 아시겠죠?:)
- 히만슈
Konsolebox가 말한 것처럼, 당신은 스스로 bash를 해킹해야 합니다.여기 이것을 어떻게 달성할 수 있는지에 대한 꽤 좋은 예가 있다.stderred 저장소(실제로 stdout을 색칠하기 위한 의미)는 빌드 방법에 대한 지침을 제공합니다.
해 보았다:하다: 새로운 파일 기술자를 정의하다.bashrc
exec 41>/tmp/my_console_log
는 임의)및('번호')stderred.c따라서 내용도 fd 41에 쓰이게 됩니다.동작은 했지만, NUL 바이트의 부하와 이상한 포맷이 포함되어 있습니다.기본적으로 바이너리 데이터이기 때문에 읽을 수 없습니다.C에 대한 이해가 좋은 사람이 시도해 볼 수 있을 것 같습니다.
이 경우 마지막 인쇄된 라인을 얻기 위해 필요한 모든 것은 다음과 같습니다.tail -n 1 [logfile]
이 답변이 필요한 이유를 정확히 알 수 없기 때문에 이 답변은 관련이 없을 수 있습니다.할 수 .netstat >> output.txt하지만 그걸 찾으시는 건 아닌 것 같은데요
물론 프로그래밍 옵션도 있습니다.명령어를 실행한 후에 위의 텍스트파일을 읽어 변수와 관련짓는 프로그램만 있으면 됩니다.또, 내가 선택한 언어인 루비에서는, 「backticks」를 사용해 커맨드 아웃풋의 변수를 작성할 수 있습니다.
output = `ls` #(this is a comment) create variable out of command
if output.include? "Downloads" #if statement to see if command includes 'Downloads' folder
print "there appears to be a folder named downloads in this directory."
else
print "there is no directory called downloads in this file."
end
한다: ".rb"ruby file.rb명령어를 사용하여 변수를 생성하여 조작할 수 있습니다.
이전 명령어를 재계산하지 않으려면 현재 터미널 버퍼를 스캔하여 마지막 명령어의 -supplied 출력을 추측하고 클립보드에 복사한 후 단말기에 입력하는 매크로를 만들 수 있습니다.
18에서 1행의 Ubuntu 18.04로 )에할 수 .gnome-terminal를 참조해 주세요.
합니다.xdootool,xclip,ruby
»gnome-terminal에 Preferences -> Shortcuts -> Select all로 설정합니다.Ctrl+shift+a.
다음 루비 스크립트를 만듭니다.
cat >${HOME}/parse.rb <<EOF
#!/usr/bin/ruby
stdin = STDIN.read
d = stdin.split(/\n/)
e = d.reverse
f = e.drop_while { |item| item == "" }
g = f.drop_while { |item| item.start_with? "${USER}@" }
h = g[0]
print h
EOF
키보드 설정에서 다음 키보드숏컷을 추가합니다.
bash -c '/bin/sleep 0.3 ; xdotool key ctrl+shift+a ; xdotool key ctrl+shift+c ; ( (xclip -out | ${HOME}/parse.rb ) > /tmp/clipboard ) ; (cat /tmp/clipboard | xclip -sel clip ) ; xdotool key ctrl+shift+v '
위의 바로 가기:
- 현재 터미널 버퍼를 클립보드에 복사합니다.
- 마지막 명령어의 출력을 추출합니다(1행만).
- 현재 단말기에 입력합니다.
지금 당장 실행하려고 할 시간이 없다는 생각이 나요.
하지만 다음과 같은 작업을 수행하면 어떻게 됩니까?
$ MY_HISTORY_FILE = `get_temp_filename`
$ MY_HISTORY_FILE=$MY_HISTORY_FILE bash -i 2>&1 | tee $MY_HISTORY_FILE
$ some_command
$ cat $MY_HISTORY_FILE
$ # ^You'll want to filter that down in practice!
IO 버퍼링에 문제가 있을 수 있습니다.또한 파일이 너무 커질 수 있습니다.누군가는 이 문제들에 대한 해결책을 생각해내야 할 것이다.
스크립트 명령어를 사용하면 도움이 될 것 같습니다.뭐랄까...
스크립트 -c bash -qf fifo_pid
해석 후 bash 기능을 사용하여 설정.
중단 없는 명령어 데모만:http://asciinema.org/a/395092
명령어를 , 「해킹」을 .script하여 화면 세션 합니다.bash-linux에서 bashrc로 이동합니다.
현재 답변 중 어느 것도 실제 해결책이 아닙니다. 요점을 놓쳤기 때문입니다.다음은 명령어의 출력을 읽는 방법입니다.
- 검사한 후에요
- 그들을 두 번 처형하지 않으면 대혼란을 일으킬 수 있다.
- SSD를 모두 사용하는 임시 파일이 없습니다.
올바른 질문
먼저 셸이 출력을 전혀 인식하지 못한다는 것을 깨달아야 합니다.그것에 초점을 맞춘 답변은 모두 파기할 수 있습니다.
stdin, stdout r stderr 3 의 、 stderr 3 가 、 stderr 가 3 가 。그것들은 또한 다음과 같이 이용할 수 있다./proc/self/[0-2] ★★★★★★★★★★★★★★★★★」/dev/pts/[0-2].
이것들은 의사 터미널 슬레이브입니다.의사 터미널은 기본적으로 마스터와 슬레이브 엔드를 가진 명명된 파이프일 뿐입니다.마스터 엔드는 프로세스가 /dev/pts/ptmx를 열어서 얻는 파일 기술자에 불과합니다. (이것은 pseudo-termunal master muxer의 약자)…과거에는 이러한 파일들이 /dev/ 어딘가에 따로 있었습니다.진정한 Unix에는 (모든 것이 파일이기 때문에) 아직도 존재합니다.GNU/Linux는 이전 세대의 교훈을 다시 한 번 잊고 있습니다.그리고 그들과 함께 오는 힘을 잃었습니다.
따라서 프로세스가 내보내는 실제 데이터가 존재하는 가상 터미널 프로그램의 버퍼에 저장되게 됩니다.표준 Linux 가상 터미널 콘솔 또는 xterm, Konsole, GNOME 터미널과 같은 X 프로그램입니다.그런 다음 그래픽 API를 통해 렌더링합니다.
즉, 그 내용을 알고 싶다면, 그 프로그램들에게 물어봐야 합니다!
정답
이 표준 인터페이스는 ANSI 터미널 명령어입니다.(텍스트를 컬러풀하게 하거나 커서를 움직이거나 마우스 포인터의 위치를 찾거나 최신 단말기에서 픽셀을 그릴 수 있습니다.
안타깝게도 버퍼 접근을 지원하는 단말기는 없습니다.
게다가, 각 유저가 다른 인터페이스를 가지는 것도 곤란합니다.
다행히 버퍼 접근을 지원하는 자체 중간 레이어 가상 단말기를 삽입할 수 있습니다.
SSH를 통해 접속할 경우 세션 도중 연결이 끊길 수 있는 경우뿐만 아니라 로그인 셸로 사용하는 것이 좋습니다.또한 세션을 다른 곳으로 이동하려는 경우(예: X를 재시작하는 경우)
실제로 하는 방법, 실제로 하는 방법
?screen"에 기록할 수 . 그러면 전체 세션을 "파일"에 기록할 수 있습니다.Unix unix unix unix unix unix unix unix unix unix unix unix unix unix unix unix unix 。명명된 파이프를 사용할 수 있습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
바깥부분
'가 '외부'의.bashrc하다
if shopt -q login_shell && [[ $- == *i* ]]; then # Login + interactive?
export ANS_FIFO=/tmp/$$.history ## $$ = current shell PID.
mkfifo -m 600 $ANS_FIFO
screen -OU -L -Logfile $ANS_FIFO # With optimal mode + UTF-8
rm $ANS_FIFO # Clean up
fi
내부 부품
이제 '.$ANS_FIFO$ANS 실행 후 .$ANS다음과 같이 합니다.
export PROMPT_COMMAND+='[[ -v ANS_FIFO ]] && export ANS="$(< $ANS_FIFO)"'
서 ""가 "bash"인지 합니다.$ANS_FIFO설정되고 .$ANS '아예'라고 .bashrc
이것은 기술적으로 유효하며, 테스트(탈옥 시퀀스 및 UTF-8 포함)를 실시했습니다만,
작업 내용:
문제:이론적으로는 이것이 동작하지만 실제로는 셸이 빠르게 행업합니다.이는 명명된 파이프가 버퍼가 아니라 동기식으로 취급되기 때문입니다(Linux에서는 버퍼가 존재하며 프로그래밍 방식으로 크기를 변경할 수도 있습니다).$ANS_FIFO있으면 screen(아마도 텍스트의 한 줄)이 돌아올 때까지 쓰는 것.
- , 패턴을 받을 해, 「」( 「 서버」)를 설정하는이 생각할 수 있습니다.
$ANS럼과 .$ANS후 , 전에 는 "Dell"이 "Dell"을 의미함을 합니다.$ANS항상 어떤 것으로만 설정된다.screen마지막 프롬프트 이후 기록되었으며, 읽어도 잠기지 않습니다. - 훨씬 낫지만 어려운 또 다른 해결책은 단말기에 직접 인터페이스를 추가하는 것입니다.으로 셸의 합니다.
$ANS년 동안 처럼요.마치 전자계산기가 수십 년 동안 해왔던 것처럼요.
아쉽게도 반나절 동안 앉아있었기 때문에 지금 다른 일을 하러 가야 합니다.만약 누군가가 저보다 먼저 이것을 실행할 의향이 있다면, 제 답변을 자유롭게 수정해 주세요.할 수 없는 경우는, 자신의 답변을 추가합니다.다음에 필요할 때 내가 직접 할 수도 있고 안 할 수도 있어.:)
-exec을 사용하여 명령 출력에 대해 명령을 실행할 수 있습니다..find음음음음:
find . -name anything.out -exec rm {} \;
여기서 말하는 것은 -> 현재 폴더에서 anything.out이라는 파일을 찾습니다.파일이 발견되면 삭제합니다.찾을 수 없는 경우 -exec 이후의 나머지 부분은 건너뜁니다.
언급URL : https://stackoverflow.com/questions/24283097/reusing-output-from-last-command-in-bash
'codememo' 카테고리의 다른 글
| 셀에서 복사할 때 따옴표 생략 (0) | 2023.04.18 |
|---|---|
| bash에 함수가 존재하는지 확인합니다. (0) | 2023.04.18 |
| 어플리케이션의 기능은 정확히 무엇입니까?Excel의 CutCopyMode 속성 (0) | 2023.04.13 |
| 태스크바에 표시되는 응용 프로그램 아이콘을 할당하는 방법 (0) | 2023.04.13 |
| WPF 오류 40 BindingExpression 경로 오류: '개체'에서 속성을 찾을 수 없습니다. (0) | 2023.04.13 |