나는 bash에서 내가 실행하는 명령을 작성하고 해당 명령의 출력을 대화형 프롬프트의 파일에 작성하도록 하는 우아한 방법을 찾고 있습니다. 다음과 같은 명령을 실행하십시오.
$ls -alh > list_dir
다음과 유사한 내용이 list_dir에 기록됩니다.
$ls -alh > list_dir
total 12K
drwxr-xr-x 2 root root 4.0K Dec 21 13:30 .
drwx------ 5 root root 4.0K Dec 21 13:30 ..
-rw-r--r-- 1 root root 842 Dec 21 13:09 file
-rw-r--r-- 1 root root 0 Dec 21 13:29 file1
-rw-r--r-- 1 root root 0 Dec 21 13:29 file2
스크립트에서 작동한다고 주장하는 솔루션이 포함된 기사를 많이 찾았지만 대화형 셸에서 작동하는 기사는 없습니다. 예를 들어, 많은 사람들은 스크립트 상단에 다음을 추가할 것을 권장합니다.
set -x
셸에 이 명령을 입력하면 명령이 표준 출력으로 인쇄되지만(비록 잘 인쇄되지는 않지만) 출력 리디렉션에 해당 명령을 포함하는 방법을 찾지 못했습니다.
나는 또한 이를 수행하기 위해 스크립트를 사용하도록 제안하는 많은 사람들을 보았습니다. 이것은 내가 찾고 있는 것을 찾는 데 가장 가까운 것이지만 항상 모든 것을 문서화하고 싶지는 않습니다. 어떤 명령이 파일로 리디렉션되는지 제어하고 싶습니다.
이 문제에 대한 좋은 해결책을 아는 사람이 있습니까? 나는 일상적인 사용에 너무 부피가 크지 않은 한 더 많은 기발한 아이디어에 열려 있습니다.
답변1
set -x 옵션은 스크립트를 디버그 모드로 전환합니다. 실제 명령은 stderr에 반영됩니다. 따라서 stdout 및 stderr을 일부 파일로 리디렉션해야 합니다. 이 시도
your_script.sh &> outputfile.txt
답변2
출력은 xtrace
stderr로 전송됩니다.앞으로리디렉션이 수행되기 전에 이 명령의 평가가 포함됩니다.
그래서:
set -x # or set -o xtrace
echo test 2> file
+ echo test
stderr가 있을 곳 으로 이동한 다음 file
fd 2에서 쉘을 열고 를 실행합니다 echo test
. 가려면 다음이 + echo test
필요 file
합니다.
{ echo test; } 2> file
이번에는 명령 그룹에서 리디렉션이 수행되고 echo test
명령이 평가됩니다(그리고 + echo test
이 시점에서 stderr로 이동하게 됩니다 file
).
일부 셸(예: AT&T ) ksh
은 + 2> file
.mksh
이는 또한 해당 명령 그룹 내에서 실행되는 모든 명령의 표준 오류가 로 이동함을 의미합니다 file
. 이 문제를 해결하려면 다음을 수행해야 합니다.
set -x
{
cmd 2>&3 3>&-
} 3>&2 2> file
즉, 원래 stderr의 복사본(fd 3)을 유지하고 명령 그룹 내의 명령에 대해 복원합니다.
의 경우 또 다른 방법은 특수 변수를 bash
사용하는 것입니다 .$BASH_XTRACEFD
exec 7> file
BASH_XTRACEFD=7
set -x
echo test
당신이 하나를 원한다면좋아요 xtrace
출력해 보세요 zsh
. 또한 $PS4
특수 변수를 사용하여 사용자 정의할 수도 있습니다.
답변3
가장 간단한 해결책은 .bashrc
다음과 같이 파일에 함수를 추가하는 것입니다.
my_run(){ echo $@ eval $@ }
source .bashrc
이 기능을 꼭 추가해 보세요. 그런 다음 예제를 사용하여 명령줄에 다음을 입력합니다.
my_run ls -ahl >list_dir
.
화면에서도 출력을 보려면 다음 명령을 사용하십시오.
my_run ls -ahl | tee list_dir
함수를 사용하고 싶지 않은 경우 명령줄에서 이를 수행할 수 있는 여러 가지 방법이 있습니다.
echo "ls -ahl" >list_dir; eval $@ >>list_dir
화면에서 출력을 보려면 다음 중 하나를 수행하면 됩니다.
echo "ls -ahl" >list_dir; eval $@ | tee -a list_dir
echo "ls -ahl" | tee list_dir | bash >>list_dir