장시간 실행되는 명령이 완료되면 바탕 화면 알림


59

15 초 이상 실행 된 명령이 대화식 쉘에서 완료 될 때마다 데스크탑 알림을 받고 싶습니다.

즉, 모든 명령을 다음과 같이 포장하고 싶습니다.

start=$(date +%s);
ORIGINAL_COMMAND;
[ $(($(date +%s) - start)) -le 15 ] || notify-send "Long running command finished"

bash에서 이것을 달성하는 가장 좋은 방법은 무엇입니까?




지금 "대화식 쉘"을 추가 한 이유는 무엇입니까? 1 년 이상 원래 게시물과 관련하여 존재하는 기존 답변 중 일부가 무효화 될 수 있습니다. 대화식 쉘 전용 솔루션이 필요한 경우이 질문을 참조하는 별도의 질문을하십시오.
Sergiy Kolodyazhnyy

편집하기 전에 첫 번째 주석에서 "대화식 쉘"부분이 명확 해졌습니다. 나는 단순히 질문을 편집하고 주석을 제거했습니다. 또한 질문에 게시 된 3 줄은 스크립트에 적합합니다.
aioobe

답변:


24

당신이 원하는 https://launchpad.net/undistract-me (와 우분투 아카이브에서 설치를 sudo apt-get install undistract-me잠재적으로 장기에 추가 무언가를 추가하는 것을 기억하지 않고, (즉 자동 작업을 포함하여, 요구하고 정확하게 무엇 않습니다) 명령 실행).


1
작동하지 않는 것 같습니다. 설치 한 후 시스템을 다시 시작하고로 테스트 sleep 30했지만 알림은 없습니다.
Galgalesh

4
당신은 다음 두 줄을 추가해야합니다 .bashrc: . /usr/share/undistract-me/long-running.bash notify_when_long_running_commands_finish_install. 버그 인 것 같습니다 : github.com/jml/undistract-me/issues/23
Ludenticus

32

내가 아는 한 래퍼가 필요 합니다. 그리고 명령 실행 시간이 15 초 이상인 경우 원하는 알림을 제공 할 수 있도록 명령을 사용하려고합니다. 여기 있습니다.

wrapper(){
    start=$(date +%s)
    "$@"
    [ $(($(date +%s) - start)) -le 15 ] || notify-send "Notification" "Long\
 running command \"$(echo $@)\" took $(($(date +%s) - start)) seconds to finish"
}

이 기능을 귀하 ~/.bashrc와 소스 에 복사하십시오 ~/.bashrc.

. ~/.bashrc

사용

wrapper <your_command>

15 초 이상 걸리는 경우 명령 및 실행 시간을 설명하는 데스크탑 알림을 받게됩니다.

wrapper sudo apt-get update

데스크탑 질화 스크린 샷


1
"$@"아닙니다 $@. 큰 차이.
geirha

4
나는 wrapper입력하는 모든 명령 앞에 글을 쓰지 않기를 원합니다 .
aioobe

2
@aioobe 당신은 더 짧은 기능 이름을 사용할 수 있습니다 심지어 문자 일 수 있습니다. 래퍼는 이런 식으로 작동합니다.
souravc

3
command; alert실제로 wrapper command:-) 보다 짧다
aioobe

1
notify-send오랫동안 만료 하지 않으려면 알림 보내기 사용자 지정 시간 초과 (밀리 초)를 지정하십시오. 예notify-send --expire-time 999999999 ...
Bryce Guinta

26

~/.bashrc별칭이 alert정의 :

alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'

명령 실행 완료를 알리는 데 사용할 수 있습니다.

용법:

$ the_command; alert

예 :

$ sudo apt-get update; alert

snap1

필요와 요구에 따라 별명을 사용자 정의 할 수 있습니다.


3
알아서 반가워요. 입력 한 모든 명령마다 경고를 추가하는 방법이 있습니까 (명령이 15 초 이상 걸린 경우에만 경고를 표시)?
aioobe

이상한 점이 이미 .bashrc에 추가 된 것입니다. 우분투에서 기본값입니까?
Vignesh

13

souravc와 같은 래퍼 이외에도 bash 에서이 작업을 수행하는 좋은 방법은 없습니다. DEBUG 트랩과 PROMPT_COMMAND를 사용하여 해킹 할 수 있습니다. 명령을 실행할 때마다 DEBUG 트랩이 트리거되고 프롬프트가 작성되기 직전에 PROMPT_COMMAND가 실행됩니다.

그래서위한 물건 ~/.bashrc과 같이된다

trap '_start=$SECONDS' DEBUG
PROMPT_COMMAND='(if (( SECONDS - _start > 15 )); then notify-send "Long running command ended"; fi)'

이것은 해킹이므로 이상한 부작용이 발생하더라도 놀라지 마십시오.


4

편집하다

TL; DR :에서 자동 완성 바로 가기를 만들고에서 .inputrc기능 .bashrc 합니다. 평소대로 명령을 실행하고 입력하지만 대신에 ENTER지정한 바로 가기를 누르십시오..inputrc

이 질문에 현상금을 낸 사람은 다음과 같이 말했습니다.

"기존의 모든 답변에는 명령 뒤에 추가 명령을 입력해야합니다. 자동으로 답변을 원합니다."

이 문제에 대한 해결책을 연구하는 동안 나는 일련의 명령에 바인딩 할 수있는 stackexchange 에서이 질문을 우연히 발견했습니다 CtrlJ. Ctrla(행의 시작 부분으로 이동), 입력 한 명령 앞에 "측정"문자열을 배치하십시오 Ctrlm(실행)

따라서 자동 완성 기능과 ENTER시간 측정을위한 별도의 명령을 수행하면서 아래에 게시 한 두 번째 기능 의 원래 목적을 유지합니다 .

현재 내 ~/.inputrc파일 의 내용은 다음과 같습니다.

"\C-j": "\C-a measure \C-m"

그리고 여기에 내용이 있습니다 .bashrc(참고로, bash를 영원히 사용하지 않았습니다-mksh를 쉘로 사용하므로 원래 게시물에서 볼 수 있습니다. 기능은 여전히 ​​동일합니다)

PS1=' serg@ubuntu [$(pwd)]
================================
$ '
function measure () 
{

/usr/bin/time --output="/home/xieerqi/.timefile" -f "%e" $@ 

if [ $( cat ~/.timefile| cut -d'.' -f1 ) -gt 15 ]; then

    notify-send "Hi , $@ is done !"

fi


}

원본 게시물

여기 내 아이디어가 있습니다-의 함수를 사용하십시오 .bashrc. 기본 원칙- /usr/bin/time명령을 완료하는 데 걸리는 시간을 측정하고 15 초를 초과하면 알림을 보냅니다.

function measure () 
{

if [ $( /usr/bin/time -f "%e" $@ 2>&1 >/dev/null ) -gt 15 ]; then

    notify-send "Hi , $@ is done !"

fi


}

여기에서 출력을 리디렉션 /dev/null하지만 출력을 보고 파일로 리디렉션 할 수도 있습니다.

훨씬 더 나은 방법 인 IMHO는 홈 폴더의 일부 파일에 시간 출력을 전송하는 것입니다 (시간 파일로 시스템을 오염시키지 않고 항상 볼 위치를 알고 있어야 함). 여기 두 번째 버전이 있습니다

function measure () 
{

/usr/bin/time --output=~/.timefile -f "%e" $@ 

if [ $( cat ~/.timefile | cut -d'.' -f1 ) -gt 15 ]; then

    notify-send "Hi , $@ is done !"

fi


}

여기에 첫 번째와 두 번째 버전의 스크린 샷이 순서대로 있습니다.

첫 번째 버전, 출력 없음 여기에 이미지 설명을 입력하십시오

출력이있는 두 번째 버전 여기에 이미지 설명을 입력하십시오


그건 그렇고, sudo 명령으로도 작동합니다. 나는 sudo lsof주로와 함께 테스트했습니다 ping -c20 google.com.
Sergiy Kolodyazhnyy

3

최근에이 목적에 맞는 도구를 만들었습니다. 랩퍼로 실행되거나 쉘 통합으로 자동 실행될 수 있습니다. 여기에서 확인하십시오 : http://ntfy.rtfd.io

설치하려면 :

sudo pip install ntfy

랩퍼로 사용하려면 다음을 수행하십시오.

ntfy done sleep 3

알림을 자동으로 받으려면 .bashrc또는에 추가하십시오 .zshrc.

eval "$(ntfy shell-integration)"

1

스크립트는 아주 잘 작동합니다. 'shebang' ( #!/bin/bash) 줄 을 포함시켜야합니다 . 여기#!/bin/bash 에 언급 된 다른 것들도 있지만 대부분 유닉스 bash 스크립트에서 잘 작동합니다. 스크립트 인터프리터에 필요하므로 스크립트 유형을 알 수 있습니다.#!/bin/bash

이것은 테스트 스크립트로 작동하는 것 같습니다.

#!/bin/bash
start=$(date +%s);
   echo Started
   sleep 20;
   echo Finished!
[ $(($(date +%s) - start)) -le 15 ] || notify-send -i dialog-warning-symbolic "Header" "Message"

이 스크립트를 수정하려면 echosleep행이 있는 곳에 명령을 입력하십시오 .

함께 참고 notify-send사용할 수있는, -i:-)뿐만 아니라 아이콘을 지정하는

또한 chmod +x /PATH/TO/FILE먼저 실행하여 실행 파일인지 확인하십시오 .



-2

이와 같은 간단한 if 문 으로이 작업을 수행 할 수도 있습니다

#!/bin/bash

START=$(date +%s)

TIME=$(($START+15))

ORIGINAL_COMMAND;

END=$(date +%s)

if [ $END -gt $TIME ]
then
    notify-send "Task Completed"
fi

고유 한 변수 이름을 사용할 수 있습니다.

이것이 작동하는지 확인할 수 있습니다. 완료하는 데 오랜 시간이 걸리는 명령과 그렇지 않은 명령이 테스트되었으며 오랜 시간이 걸리는 알림이 표시됩니다.

또한 대체하여 모든 명령이 작업을 수행 할 수 있습니다 ORIGINAL_COMMAND함께 $@하고 스크립트를 실행 ./script command.


내 답변이 다운 보트 된 이유는 무엇입니까? 나는 대답에서 내가 어디에서 잘못되었는지 알고 싶다
Rumesh

나는 그것을 내려 놓지 않았지만, 무엇이 잘못되었는지 말해 줄 것이다 : 우선, 추가 명령을 입력해야한다. 나는 현상금에 구체적으로 언급하고 싶지 않다. 둘째, 왜 calc? $((2+2))bash 내장이며 추가 프로그램이 필요하지 않습니다. 셋째 : 공백이있는 명령에서는 작동하지 않습니다. tl; dr : 다른 1 년 된 답변보다 더 나쁘다
Galgalesh

음 ..... 시작과 끝 시간은 항상 다를 것입니다. 1 초 길이의 짧은 명령이라도
Sergiy Kolodyazhnyy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.