You are not logged in.
Most of Linux users have their owned scripts in somewhere $PATH like ~/.local/bin dir. I have many too.
Later, I became concerned if I run a script accidentally from dmenu/bemenu that I intend to run it inside a terminal interactively. For example, lets say I have the following script.
#!/bin/bash
read -p "type input: " inp
echo "$inp"
Everybody knows if the script is executed in a terminal, it will prompt and wait for user's input and echo will print it out.
But if I accidentally executed it from dmenu/bemenu, the script will be running and waiting user's input in background. And
$ pgrep -f scriptname
will show a process id number. Yes, I can do
$ kill -9 <ps-number>
But it's not good.
How to make my script to run only inside terminal and avoid running background or if it was executed from dmenu/bemenu.
I googled it. I found no solution or maybe I am confusing with something. I found the following links:
https://unix.stackexchange.com/question … a-terminal
https://serverfault.com/questions/14674 … ctive-mode
But they are not working.
Thanks in advance...
Last edited by duyinthee (2023-04-08 14:22:00)
Offline
But they are not working
Please post an example of what you actually tried. You could use the '-t' flag with 'read' as a workaround...
Offline
But they are not working.
Because your dmenu run script doesn't close stdin/stdout?
Offline
You could use the '-t' flag with 'read' as a workaround...
thanks for the idea of -t flag of read.
Yes, it does work.
#!/bin/bash
read -t 3 -p "type input: " inp
[ -z "$inp" ] && exit 0
echo "$inp"
But read builtin command of dash (not bash) doesn't have -t option.
So, I am thinking of parameter $1, something like
#!/bin/dash
[ -z "$1" ] && exit 0
However, all of them are just workaround...
Please post an example of what you actually tried.
Actually, I am trying to write a script that can setup, mount and umount eCryptfs.
The script is messing up at the moment, sorry for not posting it.
Because your dmenu run script doesn't close stdin/stdout?
Yes, it does close stdin/stdout but $ pgrep -f scriptname will show a process number, It means it is running background, I think.
Offline
I have this at the beginning of my scripts, which should run only in a terminals:
#!/bin/sh
[ -t 0 ] || exit 1
...
Explanation here: https://stackoverflow.com/questions/894 … ell-script
Offline
That's the suggestion in the OPs first link and checks whether stdin is open.
Yes, it does close stdin/stdout but $ pgrep -f scriptname will show a process number, It means it is running background, I think.
That's a completely nonsensical statement.
You get a process number for every process, whether it's running in foreground or background and the forking of a process also doesn't relate to it's IO
https://superuser.com/questions/813472/ … ell-script
https://unix.stackexchange.com/question … disown-and
Offline
Yes, it does close stdin/stdout
On what do you base this conclusion? If the "[ -t 0 ]" test passes, then it most definitely has not closed stdin as it is not only not closed, but remains connected to a terminal.
If fixing your menu to close stdin isn't an option, then you should test against a variable set (but not exported) from your shellrc file.
Last edited by Trilby (2023-04-08 13:04:32)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
That's the suggestion in the OPs first link and checks whether stdin is open.
duyinthee wrote:Yes, it does close stdin/stdout but $ pgrep -f scriptname will show a process number, It means it is running background, I think.
That's a completely nonsensical statement.
You get a process number for every process, whether it's running in foreground or background and the forking of a process also doesn't relate to it's IO
Respectfully, I think I am not smart enough.
Anyhow, dogknowsnx saw what I am trying.
Please post an example of what you actually tried. You could use the '-t' flag with 'read' as a workaround...
Now, I am using the following workarounds for my scripts.
You could use the '-t' flag with 'read' as a workaround...
thanks for the idea of -t flag of read.
Yes, it does work.#!/bin/bash read -t 3 -p "type input: " inp [ -z "$inp" ] && exit 0 echo "$inp"
But read builtin command of dash (not bash) doesn't have -t option.
So, I am thinking of parameter $1, something like#!/bin/dash [ -z "$1" ] && exit 0
Thank you all for helps.
Offline
If you prefer a non-workaround, please re-read/consider post #7 - It's not so much about whether (you think) you're smart enough, but doing the smart thing (If you're able to learn one language, you can basically learn any language - programming languages included).
Offline
Knowing how things work isn't related to smartness, you're just blindly guesssing and making false assumptions.
Did you read the links to understand the various detachement approaches and did you compare them to the actual invocation in your dmenu script?
Alternatively you could go for Trilby's 2nd suggestion and test for an environment variable that indicates the context.
Since your dmenu script might pick up the environment from an interactive shell it might be better to explicitly export a variable from the dmenu script and unset it w/ your interactive shell RC.
But testing for available stdin/stdout and explicitly closing that from the dmenu script is the by far more generic and robust approach.
Testing $1 only makes sense if you always call the script w/ a parameter but do never call it accidentally w/ a parameter from dmenu.
$1 isn't related to the IO
Offline
... it might be better to explicitly export a variable from the dmenu script and unset it w/ your interactive shell RC.
I agree that this would be better than my secondary suggestion. But if they are to modify the dmenu_run (or equivalent) script anyways, they may as well fix it properly by closing stdin (and / or redirecting it from /dev/null) which would be far better than either of the environment variable options.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
... still trying to figure out how to test against a variable set.
But I am happy with the workarounds at this moment. I am not worried any more for accidentally running the script from dmenu/bemenu.
#!/bin/bash
read -e -t 3 -i "Yes" -p "say Yes in 3 sec: " yescontinue
[ -z "$yescontinue" ] && notify-send -t 3000 "the script has been closed" "for no user input" && exit 0
echo "continue..."
echo "$yescontinue" > /dev/null
if [[ "$1" == "--prvdir" && ! -z "$2" ]]; then
echo "private directory name was given..."
else
notify-send -t 3000 "the script has been closed" "private directory was not given"
exit 0
fi
if lsmod | grep -wq "^ecryptfs"; then
echo "module was loaded..."
else
echo "load ecryptfs kernel module first"
echo "run # modprobe ecryptfs"
exit 0
fi
if which ecryptfs-wrap-passphrase > /dev/null 2>&1; then
echo "commands are available..."
else
echo "commands are not available"
echo "install <ecryptfs-utils> package"
exit 0
fi
mkdir -p $HOME/.myprivatedata
prvd=$HOME/.myprivatedata/"$2"
prvs=$HOME/.myprivatedata/."$2"
if df -T | grep -wq "$prvd"; then
echo "already mounted, check first"
exit 0
fi
if [ -d "$prvd" ]; then
echo ""$prvd" exits, check first"
exit 0
fi
if [ -d "$prvs" ]; then
echo ""$prvs" exits, check first"
exit 0
fi
mkdir -p "$prvd" "$prvs"
mkdir -p ~/.ecryptfs
wppf=~/.ecryptfs/"$2".wp
conf=~/.ecryptfs/"$2".conf
sigf=~/.ecryptfs/"$2".sig
if [[ -f "$wppf" && -f "$conf" && -f "$sigf" ]]; then
echo "all config files exit, trying mount first..."
echo "if it didn't work, delete all config files or change private directory name, and rerun this script"
mount.ecryptfs_private "$2"
exit 0
else
echo "continue for creating config files..."
fi
ecryptfs-wrap-passphrase ~/.ecryptfs/"$2".wp
echo "Passphrase has been wrapped into ~/.ecryptfs/"$2".wp file."
echo "$prvs" "$prvd" ecryptfs > ~/.ecryptfs/"$2".conf
( stty -echo; printf "Passphrase: " 1>&2; read PASSWORD; stty echo; echo $PASSWORD; ) | \
ecryptfs-insert-wrapped-passphrase-into-keyring ~/.ecryptfs/"$2".wp - > /tmp/ecryptfs-insert-key
sigkey=$(cat /tmp/ecryptfs-insert-key | awk -F '[][]' '/Inserted auth tok with sig/ {print $2}')
echo "$sigkey" > ~/.ecryptfs/"$2".sig
echo "$sigkey" >> ~/.ecryptfs/"$2".sig
echo "config files have been created successfully and trying to mount..."
mount.ecryptfs_private "$2"
rm /tmp/ecryptfs-insert-key
df -T | grep "$prvd"
Thank you all.
Last edited by duyinthee (2023-04-09 03:18:27)
Offline
https://man.archlinux.org/man/core/coreutils/test.1.en
Basically
[ -z "$FOO" ] && echo bar
[ -z "$PATH" ] && echo bar
But unless you can rely on shell specifics, the problem is s a bit more nuanced w/ this approach, https://stackoverflow.com/questions/360 … et-in-bash
If you revert the approach and test for a variable that's explicitly set to a defined value, it becomes easier.
CONTEXT_DMENU="dmenu"
[ "$CONTEXT_DMENU" = "dmenu" ] && echo bar
unset CONTEXT_DMENU
[ "$CONTEXT_DMENU" = "dmenu" ] && echo bar
However:
But testing for available stdin/stdout and explicitly closing that from the dmenu script is the by far more generic and robust approach.
But if they are to modify the dmenu_run (or equivalent) script anyways, they may as well fix it properly by closing stdin (and / or redirecting it from /dev/null)
Offline
`tty` command from coreutils. E.g.
tty -s || exit 1
Offline
Thanks...
Respectfully, to produce a scenario, could anyone please put the following small script in anywhere of $PATH and execute via dmenu/bemenu (not in terminal).
#!/bin/bash
tty -s || exit 0
notify-send "the script was executed via dmenu" "the script did not stop at the line above \"tty -s || exit 0\""
.
The result I want is that if I execute the script from dmenu, I want the script to stop at the line tty -s || exit 0
But it doesn't. It always continue to the line of notify-send ....
Is it only me that tty -s || exit 0 doesn't work?
Last edited by duyinthee (2023-04-12 02:52:18)
Offline
That command "works" in the sense that it does exactly what it's supposed to - the problem is that even what it's supposed to do isn't really relevant to your problem.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
Yes, I do agree.
That command "works" in the sense that it does exactly what it's supposed to - the problem is that even what it's supposed to do isn't really relevant to your problem.
That's why I am looking for a way other than that command.
Last edited by duyinthee (2023-04-12 03:04:43)
Offline
An approach that would work has been provided several times in this thread, most recently in post #13.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
dmenu_run just passes entered string to shell:
#!/bin/sh
dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
From script's point of view there is no difference between running "in terminal" or "from dmenu": it is running in the same envoronment from which dmenu_run is invoked.
Offline
Unless, of course, you take the suggestion of the correct approach(es) that have been outlined several times.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
dmenu_run just passes entered string to shell:
#!/bin/sh dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
From script's point of view there is no difference between running "in terminal" or "from dmenu": it is running in the same envoronment from which dmenu_run is invoked.
Thanks, launching dmenu by that way makes tty -s || exit 1 works.
From script's point of view there is no difference between running "in terminal" or "from dmenu": it is running in the same envoronment from which dmenu_run is invoked.
noted with thanks.
Last edited by duyinthee (2023-04-12 04:26:22)
Offline
Thanks, launching dmenu by that way makes tty -s || exit 1 works.
In what way? What was posted is the default content of dmenu_run. What were you doing before?
Anything that allows for the `tty -s || exit` line to work would also allow the `[ -t 0 ]` test to work as they do exactly the same thing, except the latter doesn't require calling an external binary.
Last edited by Trilby (2023-04-12 12:16:10)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
In what way? What was posted is the default content of dmenu_run. What were you doing before?
Yes, right. Thanks for correcting me. What I were doing before was testing with bemenu (because I am in sway) all the time. I thought they will be same in the sense of what I was trying.
Therefore, I checked everything with both of dmenu and bemenu. According to my tests (I'm not sure, but this is what I found so far), tty -s || exit 0 works with dmenu as I expected. I think, I did messing up this thread by my carelessness. Sorry!
Last edited by duyinthee (2023-04-13 03:16:38)
Offline