You are not logged in.

#1 2023-04-08 04:05:56

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

[SOLVED] how to make a script to run only in terminal?

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

#2 2023-04-08 06:38:50

dogknowsnx
Member
Registered: 2021-04-12
Posts: 648

Re: [SOLVED] how to make a script to run only in terminal?

duyinthee wrote:

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...


Notifications for Arch Linux package updates
RI - Rest your Eyes and Self

"We are eternal, all this pain is an illusion" - Maynard James Keenan

Offline

#3 2023-04-08 07:31:54

seth
Member
Registered: 2012-09-03
Posts: 49,951

Re: [SOLVED] how to make a script to run only in terminal?

But they are not working.

Because your dmenu run script doesn't close stdin/stdout?

Offline

#4 2023-04-08 09:03:56

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

#5 2023-04-08 10:12:17

ua4000
Member
Registered: 2015-10-14
Posts: 402

Re: [SOLVED] how to make a script to run only in terminal?

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

#6 2023-04-08 12:57:07

seth
Member
Registered: 2012-09-03
Posts: 49,951

Re: [SOLVED] how to make a script to run only in terminal?

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

#7 2023-04-08 12:59:33

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] how to make a script to run only in terminal?

duyinthee wrote:

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

#8 2023-04-08 14:19:58

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

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.

dogknowsnx wrote:

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

#9 2023-04-08 14:34:31

dogknowsnx
Member
Registered: 2021-04-12
Posts: 648

Re: [SOLVED] how to make a script to run only in terminal?

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).


Notifications for Arch Linux package updates
RI - Rest your Eyes and Self

"We are eternal, all this pain is an illusion" - Maynard James Keenan

Offline

#10 2023-04-08 14:35:18

seth
Member
Registered: 2012-09-03
Posts: 49,951

Re: [SOLVED] how to make a script to run only in terminal?

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

#11 2023-04-08 15:26:15

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] how to make a script to run only in terminal?

seth wrote:

... 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

#12 2023-04-09 03:07:25

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

... 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

#13 2023-04-09 07:51:05

seth
Member
Registered: 2012-09-03
Posts: 49,951

Re: [SOLVED] how to make a script to run only in terminal?

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:

seth wrote:

But testing for available stdin/stdout and explicitly closing that  from the dmenu script is the by far more generic and robust approach.

Trilby wrote:

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

#14 2023-04-12 02:24:43

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 237

Re: [SOLVED] how to make a script to run only in terminal?

`tty` command from coreutils. E.g.

tty -s || exit 1

Offline

#15 2023-04-12 02:50:59

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

#16 2023-04-12 02:54:15

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

#17 2023-04-12 03:04:21

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

#18 2023-04-12 03:16:25

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

#19 2023-04-12 03:35:57

dimich
Member
From: Kharkiv, Ukraine
Registered: 2009-11-03
Posts: 237

Re: [SOLVED] how to make a script to run only in terminal?

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

#20 2023-04-12 03:42:40

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

#21 2023-04-12 04:13:02

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

dimich wrote:

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

#22 2023-04-12 12:12:11

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [SOLVED] how to make a script to run only in terminal?

duyinthee wrote:

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

#23 2023-04-13 03:03:56

duyinthee
Member
Registered: 2015-06-14
Posts: 222
Website

Re: [SOLVED] how to make a script to run only in terminal?

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

Board footer

Powered by FluxBB