When you double-click a bash script, Ubuntu asks if the user wants to Display, Run, or Run In Terminal...
Is there a way within the script to determine if the user ch开发者_如何学Pythonose "Run In Terminal"?
Strictly speaking, you can't tell whether the user chose "Run In Terminal" after clicking on the script, or fired up a terminal and ran the script from there. But the commands below should help you, especially [ -t 2 ]
.
if [ -t 1 ]; then
echo "Standard output is a terminal."
echo "This means a terminal is available, and the user did not redirect the script's output."
fi
if [ -t 2 ]; then
echo "Standard error is a terminal." >&2
echo "If you're going to display things for the user's attention, standard error is normally the way to go." >&2
fi
if tty >/dev/null; then
echo "Standard input is a terminal." >$(tty)
echo "The tty command returns the name of the terminal device." >$(tty)
fi
echo "This message is going to the terminal if there is one." >/dev/tty
echo "/dev/tty is a sort of alias for the active terminal." >/dev/tty
if [ $? -ne 0 ]; then
: # Well, there wasn't one.
fi
if [ -n "$DISPLAY" ]; then
xmessage "A GUI is available."
fi
Here is an example:
#!/bin/bash
GRAND_PARENT_PID=$(ps -ef | awk '{ print $2 " " $3 " " $8 }' | \
grep -P "^$PPID " | awk '{ print $2 }')
GRAND_PARENT_NAME=$(ps -ef | awk '{ print $2 " " $3 " " $8 }' \
| grep -P "^$GRAND_PARENT_PID " | awk '{ print $3 }')
case "$GRAND_PARENT_NAME" in
gnome-terminal)
echo "I was invoked by gnome-terminal"
;;
xterm)
echo "I was invoked by xterm"
;;
*)
echo "I was invoked by someone else"
esac
Now, let me explain this in a little more details. In the case when script is executed by (in) a terminal, its parent process is always a shell itself. This is because terminal emulators run shell to invoke scripts. So the idea is to look at a grandparent process. If grandparent process is a terminal then you can assume that your script was invoked from a terminal. Otherwise, it was invoked by something else, for example, Nautilus, which is Ubuntu's default file browser.
The following command gives you a parent process ID.
ps -ef | awk '{ print $2 " " $3 " " $8 }' | grep -P "^$PPID " | awk '{ print $2 }'
And this command is giving you a name of your parent's parent process.
ps -ef | awk '{ print $2 " " $3 " " $8 }' | grep -P "^$GRAND_PARENT_PID " | awk '{ print $3 }'
And the final switch statement just compares grandparent process name with some known terminal emulators.
Never tried it, but probably this works:
if [ -t 1 ] ;
Although it would also be false if the output it piped...
精彩评论