Skip to content

Commit ff09377

Browse files
Fix termux-notification and termux-toast from hanging when running from background
In termux-notification, if content is not passed as an argument and then using `[ -t 0 ]` to detect if stdin is also not available does not work for background commands since that is only meant to check if stdin is open and is associated with a terminal. When running in background, the check will fail, since stdin will not be attached to a terminal, but moreover, no data will be available on stdin either and termux-api will hang forever waiting for input. In termux-toast, similar thing happens where if toast text argument is not passed, it is assumed that data will be available on stdin, which it may not be, making termux-api hang forever waiting for input. Now for both, if arguments are not passed, then stdin is attempted to be read directly with a 3s timeout without relying on termux-api. If no data is available on stdin, then an empty string will be passed, after aborting after 3s. Fixes termux/termux-app#1925 Thanks to @krystean for investigating the issue.
1 parent e5860f4 commit ff09377

2 files changed

Lines changed: 116 additions & 93 deletions

File tree

scripts/termux-notification

Lines changed: 86 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3,71 +3,79 @@ set -e -u -f
33

44
SCRIPTNAME=termux-notification
55
show_usage () {
6-
echo "Usage: termux-notification [options]"
7-
echo "Display a system notification. Content text is specified using -c/--content or read from stdin."
8-
echo "Please read --help-actions for help with action arguments."
9-
echo " --action action action to execute when pressing the notification"
10-
echo " --alert-once do not alert when the notification is edited"
11-
echo " --button1 text text to show on the first notification button"
12-
echo " --button1-action action action to execute on the first notification button"
13-
echo " --button2 text text to show on the second notification button"
14-
echo " --button2-action action action to execute on the second notification button"
15-
echo " --button3 text text to show on the third notification button"
16-
echo " --button3-action action action to execute on the third notification button"
17-
echo " -c/--content content content to show in the notification. Will take precedence over stdin."
18-
echo " --group group notification group (notifications with the same group are shown together)"
19-
echo " -h/--help show this help"
20-
echo " --help-actions show the help for actions"
21-
echo " -i/--id id notification id (will overwrite any previous notification with the same id)"
22-
echo " --icon icon-name set the icon that shows up in the status bar. View available icons at"
23-
echo " https://material.io/resources/icons/ (default icon: event_note)"
24-
echo " --image-path path absolute path to an image which will be shown in the notification"
25-
echo " --led-color rrggbb color of the blinking led as RRGGBB (default: none)"
26-
echo " --led-off milliseconds number of milliseconds for the LED to be off while it's flashing (default: 800)"
27-
echo " --led-on milliseconds number of milliseconds for the LED to be on while it's flashing (default: 800)"
28-
echo " --on-delete action action to execute when the the notification is cleared"
29-
echo " --ongoing pin the notification"
30-
echo " --priority prio notification priority (high/low/max/min/default)"
31-
echo " --sound play a sound with the notification"
32-
echo " -t/--title title notification title to show"
33-
echo " --vibrate pattern vibrate pattern, comma separated as in 500,1000,200"
34-
echo " --type type notification style to use (default/media)"
35-
echo "Media actions (available with --type \"media\"):"
36-
echo " --media-next action to execute on the media-next button"
37-
echo " --media-pause action to execute on the media-pause button"
38-
echo " --media-play action to execute on the media-play button"
39-
echo " --media-previous action to execute on the media-previous button"
40-
exit 0
6+
echo "Usage: termux-notification [options]"
7+
echo "Display a system notification. Content text is specified using -c/--content or read from stdin."
8+
echo "Please read --help-actions for help with action arguments."
9+
echo " --action action action to execute when pressing the notification"
10+
echo " --alert-once do not alert when the notification is edited"
11+
echo " --button1 text text to show on the first notification button"
12+
echo " --button1-action action action to execute on the first notification button"
13+
echo " --button2 text text to show on the second notification button"
14+
echo " --button2-action action action to execute on the second notification button"
15+
echo " --button3 text text to show on the third notification button"
16+
echo " --button3-action action action to execute on the third notification button"
17+
echo " -c/--content content content to show in the notification. Will take"
18+
echo " precedence over stdin. If content is not passed as"
19+
echo " an argument or with stdin, then there will be a 3s delay."
20+
echo " --group group notification group (notifications with the same"
21+
echo " group are shown together)"
22+
echo " -h/--help show this help"
23+
echo " --help-actions show the help for actions"
24+
echo " -i/--id id notification id (will overwrite any previous notification"
25+
echo " with the same id)"
26+
echo " --icon icon-name set the icon that shows up in the status bar. View"
27+
echo " available icons at https://material.io/resources/icons/"
28+
echo " (default icon: event_note)"
29+
echo " --image-path path absolute path to an image which will be shown in the"
30+
echo " notification"
31+
echo " --led-color rrggbb color of the blinking led as RRGGBB (default: none)"
32+
echo " --led-off milliseconds number of milliseconds for the LED to be off while"
33+
echo " it's flashing (default: 800)"
34+
echo " --led-on milliseconds number of milliseconds for the LED to be on while"
35+
echo " it's flashing (default: 800)"
36+
echo " --on-delete action action to execute when the the notification is cleared"
37+
echo " --ongoing pin the notification"
38+
echo " --priority prio notification priority (high/low/max/min/default)"
39+
echo " --sound play a sound with the notification"
40+
echo " -t/--title title notification title to show"
41+
echo " --vibrate pattern vibrate pattern, comma separated as in 500,1000,200"
42+
echo " --type type notification style to use (default/media)"
43+
echo "Media actions (available with --type \"media\"):"
44+
echo " --media-next action to execute on the media-next button"
45+
echo " --media-pause action to execute on the media-pause button"
46+
echo " --media-play action to execute on the media-play button"
47+
echo " --media-previous action to execute on the media-previous button"
48+
exit 0
4149
}
4250

4351
show_help_actions () {
44-
echo "This help refers to the arguments to options like --action, --on-delete, --button-1-action and --media-next."
45-
echo
46-
echo "All these commands take an action string as their argument, which is fed to \`dash -c\`."
47-
echo "A few important things must be kept in mind when using actions:"
48-
echo
49-
echo "You should use actions that do things outside of the terminal, like --action \"termux-toast hello\"."
50-
echo "Anything that outputs to the terminal is useless, so the output should either be redirected (--action \"ls > ~/ls.txt\") or shown to the user in a different way (--action \"ls|termux-toast\")."
51-
echo
52-
echo "Running more than one command in a single action is as easy as"
53-
echo "--action \"command1; command2; command3\""
54-
echo "or"
55-
echo "--action \"if [ -e file ]; then termux-toast yes; else termux-toast no; fi\"."
56-
echo
57-
echo "For anything more complex, you should put your script in a file, make it executable, and use that as the action:"
58-
echo "--action ~/bin/script"
59-
echo
60-
echo "The action is run in a different environment (not a subshell). Thus your environment is lost (most notably \$PATH), and ~/.profile is not sourced either. So if you need your \$PATH you should either:"
61-
echo " - if the action is a script, set it explicitly in the script (e.g. export PATH=\"\$HOME/bin:\$PATH\")"
62-
echo " - or use something like --action \"bash -l -c 'command1; command2'\")."
63-
echo
64-
echo "On Android N or above, you can use the special variable \$REPLY in your actions to use Android's Direct Reply feature."
65-
echo "This prompts the user to enter some text directly in the notification, which is then substituted into your action."
66-
echo " - termux-notification --button1 \"Answer\" --button1-action \"termux-toast \\\$REPLY\""
67-
echo "will call the action:"
68-
echo " - termux-toast \"Some text entered by the user\""
69-
echo "Be careful to escape shell commands correctly for single or double quotes, e.g."
70-
echo " --button1-action 'something \$REPLY' or --button1-action \"something \\\$REPLY\""
52+
echo "This help refers to the arguments to options like --action, --on-delete, --button-1-action and --media-next."
53+
echo
54+
echo "All these commands take an action string as their argument, which is fed to \`dash -c\`."
55+
echo "A few important things must be kept in mind when using actions:"
56+
echo
57+
echo "You should use actions that do things outside of the terminal, like --action \"termux-toast hello\"."
58+
echo "Anything that outputs to the terminal is useless, so the output should either be redirected (--action \"ls > ~/ls.txt\") or shown to the user in a different way (--action \"ls|termux-toast\")."
59+
echo
60+
echo "Running more than one command in a single action is as easy as"
61+
echo "--action \"command1; command2; command3\""
62+
echo "or"
63+
echo "--action \"if [ -e file ]; then termux-toast yes; else termux-toast no; fi\"."
64+
echo
65+
echo "For anything more complex, you should put your script in a file, make it executable, and use that as the action:"
66+
echo "--action ~/bin/script"
67+
echo
68+
echo "The action is run in a different environment (not a subshell). Thus your environment is lost (most notably \$PATH), and ~/.profile is not sourced either. So if you need your \$PATH you should either:"
69+
echo " - if the action is a script, set it explicitly in the script (e.g. export PATH=\"\$HOME/bin:\$PATH\")"
70+
echo " - or use something like --action \"bash -l -c 'command1; command2'\")."
71+
echo
72+
echo "On Android N or above, you can use the special variable \$REPLY in your actions to use Android's Direct Reply feature."
73+
echo "This prompts the user to enter some text directly in the notification, which is then substituted into your action."
74+
echo " - termux-notification --button1 \"Answer\" --button1-action \"termux-toast \\\$REPLY\""
75+
echo "will call the action:"
76+
echo " - termux-toast \"Some text entered by the user\""
77+
echo "Be careful to escape shell commands correctly for single or double quotes, e.g."
78+
echo " --button1-action 'something \$REPLY' or --button1-action \"something \\\$REPLY\""
7179
}
7280

7381
OPT_ACTION=""
@@ -79,6 +87,7 @@ OPT_BUTTON2_TEXT=""
7987
OPT_BUTTON3_ACTION=""
8088
OPT_BUTTON3_TEXT=""
8189
OPT_CONTENT=""
90+
OPT_CONTENT_PASSED=""
8291
OPT_GROUP=""
8392
OPT_ID=""
8493
OPT_ICON=""
@@ -99,9 +108,9 @@ OPT_TYPE=""
99108
OPT_VIBRATE=""
100109

101110
TEMP=`getopt \
102-
-n $SCRIPTNAME \
103-
-o hc:i:t: \
104-
--long action:,alert-once,\
111+
-n $SCRIPTNAME \
112+
-o hc:i:t: \
113+
--long action:,alert-once,\
105114
button1:,button1-action:,\
106115
button2:,button2-action:,\
107116
button3:,button3-action:,\
@@ -112,8 +121,8 @@ media-previous:,media-next:,media-play:,media-pause:,\
112121
on-delete:,ongoing,\
113122
priority:,\
114123
sound,title:,type:,vibrate: \
115-
-s bash \
116-
-- "$@"`
124+
-s bash \
125+
-- "$@"`
117126
eval set -- "$TEMP"
118127

119128
while true; do
@@ -126,7 +135,7 @@ while true; do
126135
--button2-action) OPT_BUTTON2_ACTION="$2"; shift 2;;
127136
--button3) OPT_BUTTON3_TEXT="$2"; shift 2;;
128137
--button3-action) OPT_BUTTON3_ACTION="$2"; shift 2;;
129-
-c | --content) OPT_CONTENT="$2"; shift 2;;
138+
-c | --content) OPT_CONTENT_PASSED=1; OPT_CONTENT="$2"; shift 2;;
130139
--group) OPT_GROUP="$2"; shift 2;;
131140
-h | --help) show_usage;;
132141
--help-actions) show_help_actions; exit 0;;
@@ -187,10 +196,13 @@ if [ -n "$OPT_TITLE" ]; then set -- "$@" --es title "$OPT_TITLE"; fi
187196
if [ -n "$OPT_TYPE" ]; then set -- "$@" --es type "$OPT_TYPE"; fi
188197
if [ -n "$OPT_VIBRATE" ]; then set -- "$@" --ela vibrate "$OPT_VIBRATE"; fi
189198

190-
if [ -n "$OPT_CONTENT" ] || [ -t 0 ]; then
191-
# we either have some content, so it takes precedence over STDIN
192-
# or have no STDIN, so we must use content even if empty
193-
echo "$OPT_CONTENT" | @TERMUX_PREFIX@/libexec/termux-api Notification "$@"
194-
else # use STDIN
195-
@TERMUX_PREFIX@/libexec/termux-api Notification "$@"
199+
# If content was not passed as an argument, then attempt to read from STDIN with a 3s timeout
200+
# Content argumOPT_CONTENT="$(echo "$OPT_CONTENT")" # trim trailing newlinesent takes precedence over STDIN
201+
if [[ "$OPT_CONTENT_PASSED" != "1" ]]; then
202+
set +e; IFS= read -t 3 -r -d '' OPT_CONTENT; set -e;
196203
fi
204+
205+
# Trim trailing newlines
206+
OPT_CONTENT="$(echo "$OPT_CONTENT")"
207+
208+
echo "$OPT_CONTENT" | @TERMUX_PREFIX@/libexec/termux-api Notification "$@"

scripts/termux-toast

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,46 @@ set -e -u
33

44
SCRIPTNAME=termux-toast
55
show_usage () {
6-
echo "Usage: termux-toast [-b bgcolor] [-c color] [-g gravity] [-s] [text]"
7-
echo "Show text in a Toast (a transient popup). The text to show is either supplied as arguments or read from stdin if no arguments are given."
8-
echo " -h show this help"
9-
echo " -b set background color (default: gray)"
10-
echo " -c set text color (default: white)"
11-
echo " -g set position of toast: [top, middle, or bottom] (default: middle)"
12-
echo " -s only show the toast for a short while"
13-
echo "NOTE: color can be a standard name (i.e. red) or 6 / 8 digit hex value (i.e. \"#FF0000\" or \"#FFFF0000\") where order is (AA)RRGGBB. Invalid color will revert to default value"
14-
exit 0
6+
echo "Usage: termux-toast [-b bgcolor] [-c color] [-g gravity] [-s] [text]"
7+
echo "Show text in a Toast (a transient popup)."
8+
echo "The toast text is either supplied as arguments or read from stdin"
9+
echo "if no arguments are given. Arguments will take precedence over stdin."
10+
echo "If toast text is not passed as arguments or with stdin, then there will"
11+
echo "be a 3s delay."
12+
echo " -h show this help"
13+
echo " -b set background color (default: gray)"
14+
echo " -c set text color (default: white)"
15+
echo " -g set position of toast: [top, middle, or bottom] (default: middle)"
16+
echo " -s only show the toast for a short while"
17+
echo "NOTE: color can be a standard name (i.e. red) or 6 / 8 digit hex value (i.e. \"#FF0000\" or \"#FFFF0000\") where order is (AA)RRGGBB. Invalid color will revert to default value"
18+
exit 0
1519
}
1620

1721
PARAMS=""
1822
while getopts :hsc:b:g: option
1923
do
20-
case "$option" in
21-
h) show_usage;;
22-
s) PARAMS+=" --ez short true";;
23-
c) PARAMS+=" --es text_color $OPTARG";;
24-
b) PARAMS+=" --es background $OPTARG";;
25-
g) PARAMS+=" --es gravity $OPTARG";;
26-
?) echo "$SCRIPTNAME: illegal option -$OPTARG"; exit 1;
27-
esac
24+
case "$option" in
25+
h) show_usage;;
26+
s) PARAMS+=" --ez short true";;
27+
c) PARAMS+=" --es text_color $OPTARG";;
28+
b) PARAMS+=" --es background $OPTARG";;
29+
g) PARAMS+=" --es gravity $OPTARG";;
30+
?) echo "$SCRIPTNAME: illegal option -$OPTARG"; exit 1;
31+
esac
2832
done
2933
shift $((OPTIND-1))
3034

3135
CMD="@TERMUX_PREFIX@/libexec/termux-api Toast $PARAMS"
3236

37+
# If toast text was not passed as an argument, then attempt to read from STDIN with a 3s timeout
38+
# Toast text arguments takes precedence over STDIN
3339
if [ $# = 0 ]; then
34-
$CMD
40+
set +e; IFS= read -t 3 -r -d '' TOAST_TEXT; set -e;
3541
else
36-
echo "$@" | $CMD
42+
TOAST_TEXT="$*"
3743
fi
44+
45+
# Trim trailing newlines
46+
TOAST_TEXT="$(echo "$TOAST_TEXT")"
47+
48+
echo "$TOAST_TEXT" | $CMD

0 commit comments

Comments
 (0)