문서화 목적으로 실행하는 명령에서 stdout 및 stderr 파일로 리디렉션하는 것을 의미합니다. 예를 들어 다음을 실행합니다(내 명령은 별칭보다 덜 간단 ll
하지만 아마도 중요하지 않습니다).
$ ll > out-err.dat 2>&1
$ cat out-err.dat
drwxr-xr-x 39 us00001 us00001 4096 jul 31 14:57 ./
drwxr-xr-x 3 root root 4096 feb 2 06:06 ../
-rw------- 1 us00001 us00001 62226 jul 31 11:56 .bash_history
...
또한 문서화 목적으로 동일한 출력 파일에 사용하는 명령줄을 저장하고 싶습니다. 예상되는 동작과 출력은 다음과 같습니다.
$ [NEW COMMAND LINE]?
$ cat out-err.dat
[NEW COMMAND LINE] <- This first line would contain the command line used
drwxr-xr-x 39 us00001 us00001 4096 jul 31 14:57 ./
drwxr-xr-x 3 root root 4096 feb 2 06:06 ../
-rw------- 1 us00001 us00001 62226 jul 31 11:56 .bash_history
...
이것이 어떻게 달성될 수 있습니까? 나는 bash 스크립트를 작성하고 실행하여 명령이 별도로 기록될 수 있다는 것을 알고 있습니다. 명령줄을 파일에 반영한 다음 동일한 파일로 리디렉션하여 실행하는 스크립트를 추가로 작성할 수도 있습니다. 가능한 스크립트리스 솔루션을 찾고 있습니다.
편집하다:좋은 답변을 피드백해 주세요. 이것은 코멘트로서 적절하지 않습니다.
명령어로 테스트해봤습니다 echo_command ll echo_command.sh ../dir > out-err.dat 2>&1
. 내
스크립트에는 함수 정의가 포함되어 있습니다. 존재하지 않는 디렉토리이므로 일부 출력이 .echo_command.sh
source
../dir
stderr
방법 1: 두 가지 문제를 제외하고는 훌륭하게 작동합니다.
별칭을 이해하지 못합니다(
ll
이 경우 교체가ls
작동합니다).리디렉션 부분은 기록하지 않습니다.
방법 2: 효과는 별로 좋지 않습니다. 이제 리디렉션된 부분도 인쇄되지만 명령줄은 파일로 리디렉션되는 대신 화면에 인쇄됩니다.
편집하다: 유틸리티에 대해 게시된 의견에 대한 피드백입니다 script
. 매우 다재다능하며 대화형 셸을 생성하는
scriptreplay
. 또는 로 호출할 수 있습니다 . 마지막 형식은 OP의 목표에 해당하지만 명령 자체는 다음과 같습니다. 로그 파일에 저장되지 않습니다. (적어도 기본 사례에서는) 와 동일한 출력을 생성합니다 . 그러니 여기서는 아무 소용이 없을 것 같습니다.
script
script -c <command> <logfile>
<command> > <logfile> 2>&1
답변1
다음과 같은 기능을 사용할 수 있습니다.
echo_command() { printf '%s\n' "${*}"; "${@}"; }
예:
$ echo_command echo foo bar baz
echo foo bar baz
foo bar baz
$ echo_command uname
uname
Linux
Tim Kennedy가 말했듯이 매우 유용한 script
명령도 있습니다.
$ script session.log
Script started, file is session.log
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done, file is session.log
$ cat session.log
Script started on 2018-07-31 16:30:31-0500
$ echo foo
foo
$ echo bar
bar
$ echo baz
baz
$ exit
exit
Script done on 2018-07-31 16:30:43-0500
고쳐 쓰다
리디렉션과 기본적으로 모든 셸 구문도 기록해야 하는 경우( Command line:
실행 중인 명령을 쉽게 식별하기 위해 작은 메시지를 추가했습니다):
echo_command() {
local arg
for arg; do
printf 'Command line: %s\n' "${arg}"
eval "${arg}"
done
}
eval
인용하는 내용 에 대해 매우 주의해야 한다는 점을 기억하십시오 .
$ echo_command 'echo foo > "file 2"; cat "file 2"'
Command line: echo foo > "file 2"; cat "file 2"
foo
또한 하나의 명령 대신 동시에 여러 명령을 수락할 수도 있습니다.
$ echo_command 'echo foo' 'echo bar' 'echo baz'
Command line: echo foo
foo
Command line: echo bar
bar
Command line: echo baz
baz
답변2
xtrace
쉘의 메커니즘을 사용하여 실행 중인 명령을 stdout으로 인쇄할 수 있습니다 .
(set -x; ls -l) > out-err.dat 2>&1
$PS4
마음에 들지 않으면 기본값(대부분의 쉘에서)을 "+ "
다른 것으로 변경하십시오(접두사를 원하지 않으면 공백으로 두십시오).
기능으로는:
log_into() ( # args: output-file command args
exec > "$1" 2>&1
shift
PS4='Running: '
set -o xtrace
"$@"
)
log_into out-err.dat ls -l