터미널에서 GUI를 시작할 때 발생하는 불편함을 어떻게 없앨 수 있습니까?

터미널에서 GUI를 시작할 때 발생하는 불편함을 어떻게 없앨 수 있습니까?

나는 그래픽 데스크탑을 사용하는 것보다 터미널 창에서 GUI 애플리케이션을 시작하는 것을 선호합니다. 일반적인 불만 사항은 개발자가 이러한 유형의 사용을 예상하지 못하는 경우가 많기 때문에 응용 프로그램이 stdout 또는 stderr에 쓸모 없거나 비밀스럽거나 정보가 없는 메시지를 대량으로 인쇄한다는 것입니다. &를 사용하여 백그라운드에서 프로그램을 실행하면 작업 생성 및 종료에 대한 보고서가 생성되므로 터미널에서 더 많은 혼란이 발생합니다.

명령줄 인수를 받아들이고 자동 완성을 처리하는 이러한 문제에 대한 해결 방법은 무엇입니까?

관련된:https://stackoverflow.com/questions/7131670/make-bash-alias-that-takes-parameter

답변1

표준 오류를 즉시 리디렉션하는 것은 /dev/null이전 오류 메시지를 숨기고 오류를 진단하기 어려울 수 있으므로 좋지 않은 생각입니다. 다음 zsh 스크립트를 사용하는 것이 좋습니다 start-app.

#!/usr/bin/env zsh
coproc "$@" 2>&1
quit=$(($(date +%s)+5))
nlines=0
while [[ $((nlines++)) -lt 10 ]] && read -p -t 5 line
do
  [[ $(date +%s) -ge $quit ]] && break
  printf "[%s] %s\n" "$(date +%T)" "$line"
done &

그냥 실행해 보세요:start-app your_command argument ...

스크립트는 최대 5초 동안 최대 10줄의 메시지를 출력합니다. 그러나 애플리케이션이 즉시 충돌하는 경우(예: 분할 오류로 인해) 오류 메시지가 표시되지 않습니다. 물론 원하는 대로 이 스크립트를 다양한 방법으로 수정할 수 있습니다.

참고: zsh 에서 완성 기능을 사용하려면 start-app다음을 수행하세요.

compdef _precommand start-app

배쉬에서:

complete -F _command start-app

(에서 exectime에서 복사됨 /usr/share/bash-completion/bash_completion).

답변2

이 답변은 bash에 대한 것입니다. 예를 들어, evPDF 뷰어 Evince를 시작하는 편리한 명령을 만들기 위해 .bashrc에서 수행한 작업은 다음과 같습니다.

ev() { (evince "$1" 1>/dev/null 2>/dev/null &) }
complete -f -o default -X '!*.pdf' ev

첫 번째 줄은 함수를 정의합니다 ev. 명령줄에서 함수를 사용하면 함수 이름이 다음과 같이 인식됩니다.

ev foo.pdf

(이것은 별칭과 다른 메커니즘이며 우선 순위가 낮습니다.) stdin 및 stdout에 대한 Evince의 출력은 bitbucket(/dev/null)으로 전송됩니다. & 기호는 작업을 백그라운드에 둡니다. 명령을 괄호로 묶으면 해당 명령이 하위 쉘에서 실행되므로 백그라운드 작업 생성 또는 완료에 대한 메시지가 인쇄되지 않습니다.

내 .bashrc의 두 번째 줄은 bash의 전체 기능을 사용하여 ev 명령에 대한 인수가 pdf 확장자를 가진 파일이어야 함을 bash에 알려줍니다. 이는 내 디렉토리에 foo.tex, foo.aux 등의 파일도 있는 경우 ev fooTab을 입력하고 누르면 bash가 파일 이름을 foo.pdf로 완성한다는 것을 알게 된다는 의미입니다.

답변3

command또 다른 가능성은 다운그레이드를 사용하는 것입니다.exec특별한다음과 같은 일반 기존 내장 기능에 내장:

alias shh='command exec >/dev/null 2>&1'

이제 다음을 수행할 수 있습니다.

(shh; call some process &)

command방금 이것이 작동하지 않는다는 것을 알았습니다.zsh (대부분의 다른 쉘과 마찬가지로)하지만 작동하지 않으면 다음과 같이 할 수 있습니다.

alias shh='eval "exec >/dev/null 2>&1"'

...이것은 어디에서나 작동할 것입니다.

실제로 다음과 같이 할 수도 있습니다.

alias shh='command exec >"${O:-/dev/null}" 2>&1'

그래서 당신은 이것을 할 수 있습니다 :

O=./logfile; (shh;echo can anyone hear &)
O=; (shh; echo this\? &)
cat ./logfile

산출

can anyone hear

@vinc17의 의견에 대해 논의한 후 거의 모든 GUI 응용 프로그램의 콘솔 출력은 일반적으로 Xstty(해당 콘솔)용이라는 점에 주목할 가치가 있습니다. 파일 X에서 애플리케이션을 실행 하면 X .desktop생성된 출력이 X가상 터미널로 라우팅됩니다. 이는 X처음에 시작한 tty입니다. 이 tty 번호를 사용하여 주소를 지정할 수 있습니다 $XDG_VTNR.

그런데 이상하게도 - 이제 막 사용하기 시작해서인지 startx- 더 이상 그냥 쓸 수는 없는 것 같아요 /dev/tty$XDG_VTNR.(제 생각엔 그럴 확률이 더 높을 것 같아요)v1.16에서 최근 구현된 주요 변경 사항과 관련되어 요구 사항 대신 Xorg사용자 세션에서 실행될 수 있습니다.systemd뿌리특권.

그러나 나는 이렇게 할 수 있습니다:

alias gui='command exec >/dev/tty$((1+$XDG_VTNR)) 2>&1'

(gui; some x app &)

이제 모든 콘솔 출력이 내 pty 대신 some x app에 라우팅됩니다 . 다음과 같이 언제든지 마지막 페이지를 얻을 수 있습니다./dev/tty$((1+$XDG_VTNR))xterm

fmt </dev/vcs$((1+$XDG_VTNR))

어떤 경우든 가장 좋은 방법은 출력 로깅에만 일부 가상 터미널을 사용하는 것입니다. 이것은 일반적으로 이를 위해 이미 예약되어 있지만, 이 글을 행복하게 작성하는 데 필요한 작업을 /dev/console수행하고 싶지 않을 수도 있습니다 . 아마도 기본적으로 인쇄를 chown수행할 수 있는 기능이 있을 것이므로 그런 식으로 사용하는 것이 가능할 것이라고 생각했습니다.printk/dev/console

이를 수행하는 또 다른 방법은 구체적으로푸티이 목표를 달성하십시오. 예를 들어 xterm창을 열어두고, 실행 결과를 환경 변수에 저장하고, 해당 값을 tty출력 대상으로 사용할 수 있습니다. gui이렇게 하면 모든 로그가 별도의 로그 창으로 라우팅되며 필요에 따라 스크롤할 수 있습니다.

내가 한번 쓴 적이 있다답변bash관심이 있다면 역사와 비슷한 일을 하는 방법을 배울 수 있습니다.

관련 정보