예상대로 작동하지 않는 Ruby 스크립트의 stderr 리디렉션

예상대로 작동하지 않는 Ruby 스크립트의 stderr 리디렉션

출력 중이라고 생각되는 명령이 있습니다. 해당 명령으로 stderr리디렉션해도 여전히 출력이 화면에 인쇄되기 때문입니다.stdout/dev/null

stderr그러나 으로 리디렉션하면 /dev/null화면에 출력도 인쇄됩니다.

또한 모든 출력을 then으로 리디렉션하면 /dev/null예상대로 작동합니다.

어떻게 그래? 1>적어도 2>좀 잡아야 할까요 &>?

아래는 예입니다:

$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 1>/dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 2>/dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
$ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles &>/dev/null
$ 

복사하려면 내 프로젝트를 복제하세요.

➜  ~/D/w/tmp  rm /tmp/fakehome
➜  ~/D/w/tmp  mkdir /tmp/fakehome
➜  ~/D/w/tmp  git clone https://github.com/mbigras/mb-fullstop
Cloning into 'mb-fullstop'...
remote: Counting objects: 150, done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 150 (delta 49), reused 147 (delta 46), pack-reused 0
Receiving objects: 100% (150/150), 24.06 KiB | 0 bytes/s, done.
Resolving deltas: 100% (49/49), done.
Checking connectivity... done.
➜  ~/D/w/tmp  cd mb-fullstop
➜  mb-fullstop master ✓ git checkout fix-git-logging-to-stderr
Branch fix-git-logging-to-stderr set up to track remote branch fix-git-logging-to-stderr from origin.
Switched to a new branch 'fix-git-logging-to-stderr'
➜  mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': Cloning into 'fake-dotfiles'...
➜  mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
➜  mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 1> /dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
➜  mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles 2> /dev/null
stderr output of 'git clone https://github.com/mbigras/fake-dotfiles': fatal: destination path 'fake-dotfiles' already exists and is not an empty directory.
Error running 'git clone https://github.com/mbigras/fake-dotfiles'
checkout dir already exists, use --force to overwrite
➜  mb-fullstop fix-git-logging-to-stderr ✓ HOME=/tmp/fakehome/ bundle exec bin/fullstop https://github.com/mbigras/fake-dotfiles &> /dev/null
➜  mb-fullstop fix-git-logging-to-stderr ✓

답변1

이것은 Ruby 로깅 라이브러리의 기능입니다.메타돈이 스크립트에서 사용됩니다. 표준 출력과 표준 오류가 터미널인지 여부에 따라 다르게 동작합니다.

initialize방법 보기cli_logger.rb. 의견에 설명된 대로:

오류 유형 메시지를 두 번째 장치의 로거에 기록합니다. 오류 메시지가 표준 오류로 이동하는지 확인하는 데 유용합니다. 올바른 일을 하려면 매우 합리적이어야 합니다. 두 로그 장치가 모두 tty인 경우(예를 들어 하나는 표준 오류용이고 다른 하나는 표준 출력용) 메시지는 전체 출력 스트림에서 한 번만 나타납니다. 즉, 기록된 오류가 표시됩니다.오직표준 오류에서. 로그 장치 중 하나가 tty가 아닌 경우 모든 메시지는 +log_device+로 전송되고 오류만 +error_device+로 전송됩니다.

옳은 일을 하는 것이 현명하다는 말에 문제가 생길 수도 있습니다. 로깅 모듈에 대한 보다 합리적인 기본값은 stderr에 기록하고 stdout을 무시하는 것입니다.

관련 정보