bash echo 명령줄은 명령줄 자체에서 실행됩니다(스크립트가 아님).

bash echo 명령줄은 명령줄 자체에서 실행됩니다(스크립트가 아님).

문서화 목적으로 실행하는 명령에서 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.shsource
../dirstderr

방법 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

관련 정보