You are not logged in.

#1 2022-01-28 15:33:40

goldmund
Member
Registered: 2021-02-15
Posts: 73

[SOLVED] How to launch terminal emulator from a background script?

Hi,

I have installed udev-media-automount (recommended on Arch Wiki) to auto-mount my external drives through udev. It's working perfectly, I even "improved" it with a notification showing up when a drive gets mounted.

That notification took quite a bit of research as DBUS_SESSION_BUS_ADDRESS wasn't so easy to figure out:

DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u $username)/bus runuser -u user notify-send "$dev > $AUTOMOUNT_DIR"

Now I got an idea. It would be great to open a terminal emulator (using "st") automatically and cd into the external drive. That's even better than just a notification.

However, all my attempts to do so have failed, I haven't found a way to launch "st" from a background script as root, but run "st" as a non-root user:

# DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus runuser -u user 'st -e cd /media/mounted_drive'
runuser: failed to execute st -e cd /media/mounted_drive: No such file or directory

Then there is another question: how would you ensure that the terminal emulator stays open? Doing:

while true; do
sleep 10
done

would make the emulator unusable.

Is this even possible? Thanks!

Last edited by goldmund (2022-01-29 15:19:22)

Offline

#2 2022-01-28 15:54:43

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

https://gist.github.com/AladW/de1c5676d93d05a5a0e1

type cd

will tell you that this is a shell built-in. What you actually want to do is (I guess) to run an interactive shell and start that at the desired directory.
Try sth. like

# cd /media/mounted_drive
# DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus runuser -u user st

Offline

#3 2022-01-28 16:17:47

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

seth wrote:

https://gist.github.com/AladW/de1c5676d93d05a5a0e1

type cd

will tell you that this is a shell built-in. What you actually want to do is (I guess) to run an interactive shell and start that at the desired directory.
Try sth. like

# cd /media/mounted_drive
# DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus runuser -u user st

True! Should have thought of that before.

Unfortunately, st is now complaining that it:

can't open display

(despite DISPLAY=:0 being set)

Offline

#4 2022-01-28 16:19:33

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

runuser -u user env DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus st

?
(idk at hand what environment runuser nukes, so …)

Offline

#5 2022-01-28 16:36:00

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

seth wrote:
runuser -u user env DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus st

?
(idk at hand what environment runuser nukes, so …)

Okay, this is weird. It's still saying the same:

# runuser -u user env DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u user)/bus st
can't open display

When changing DISPLAY=:0 to DISPLAY=:1 it does:

Authorization required, but no authorization protocol specified
can't open display

I've tried DISPLAY=:1 because:

$ echo $DISPLAY
:1

Last edited by goldmund (2022-01-28 16:36:20)

Offline

#6 2022-01-28 16:41:08

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

GDM?

loginctl session-status

See the link in #2 for the XAUTHORITY variable.

Offline

#7 2022-01-28 17:02:24

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

Sorry, that code seems to me a little cryptic, I've tried hard, but don't understand it. GDM? You mean Gnome Display Manager? I am not running gnome, but dwm, and don't have a display manager.

Perhaps I should mention that I am not using xinit, but sx.

$ loginctl session-status

Offline

#8 2022-01-28 20:29:48

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

You can use that script, but instead of the "xinit" process you look for the "sx" process.
It will assign the variables properly and you can then pass them to runuser via the "-w" parameter.

Offline

#9 2022-01-28 23:32:28

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

seth wrote:

You can use that script, but instead of the "xinit" process you look for the "sx" process.
It will assign the variables properly and you can then pass them to runuser via the "-w" parameter.

Sorry for being so dumb, I am giving you a hard time.

So I put that into my script:

pid=$(pgrep -t tty$(fgconsole) sx)
pid=$(pgrep -P $pid -n)

import_environment() {
        (( pid )) && for var; do
                IFS='=' read key val < <(egrep -z "$var" /proc/$pid/environ)

                printf -v "$key" %s "$val"
                [[ ${!key} ]] && export "$key"
        done
}

import_environment DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY

runuser -u user -w DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY st

but st is still complaining:

can't open display

The above mentioned variables are not even set!

BTW, this doesn't seem to work:

$ pid=$(pgrep -t tty1 sx)
$ pgrep -P "$pid" -n
pgrep: not a number: 1035
1080
1087
1091
1092
1094
1099
(exit code 1)

What am I doing wrong?

Offline

#10 2022-01-29 08:05:05

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

"pgrep sx" matches too many processes

pid=$(pgrep -t tty$(fgconsole) "/usr/bin/sx")

Also the commas have no business being in

import_environment DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY

Offline

#11 2022-01-29 10:02:42

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

seth wrote:

"pgrep sx" matches too many processes

pid=$(pgrep -t tty$(fgconsole) "/usr/bin/sx")

Also the commas have no business being in

import_environment DISPLAY,DBUS_SESSION_BUS_ADDRESS,XAUTHORITY

Perfect, this works! A terminal window now opens when an external drive is mounted. Thank you!

Strangely,

pgrep -t tty$(fgconsole) "/usr/bin/sx"

doesn't output anything, despite the fact that:

$ which sx
/usr/bin/sx

I had to do

pgrep -t tty$(fgconsole) sx | head -n1

for it to output a pid.

Offline

#12 2022-01-29 13:25:37

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

pgrep must be reflected in "ps aux | grep sx" - I took "/usr/bin/sx" from your earlier "loginctl session-status"
You basically just have to isolate a process that's running for the current/desired user to import the environment from there.

Please always remember to mark resolved threads by editing your initial posts subject - so others will know that there's no task left, but maybe a solution to find.
Thanks.

Offline

#13 2022-01-29 15:34:10

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

Great, thanks again!

Offline

#14 2022-01-29 21:44:38

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

We'll handle this on the forum ;-)

There is just a small problem which annoys me: when the terminal window opens, I issue some commands and after a while I forget that this specific terminal was launched from the background script. When
I eventually decide to unmount the drive, umount is complaining that "target is busy", despite the fact that I have cd-ed outside the mounted directory a long time ago. Then I have to figure out which
terminal was launched from the background script (sometimes I have LOTS of terminal emulators open) and close it. Only then does umount allow me to unmount the drive.

I was wondering if there was a way to daemonize the launch of the terminal and break any connection to the background script, I have tried for example setsid:
cd "$AUTOMOUNT_DIR"
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- setsid -f /usr/local/bin/st
cd /

But that doesn't change a thing.

The trailing "cd /" won't be reached but simply forking the runuser (add a trailing "&") should™ do (because then the script continues and exits and doesn't keep the path active)

Offline

#15 2022-01-30 19:26:30

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

seth wrote:

The trailing "cd /" won't be reached but simply forking the runuser (add a trailing "&") should™ do (because then the script continues and exits and doesn't keep the path active)

I've tried that, however, none of this helps:

runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY /usr/local/bin/st &
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY '/usr/local/bin/st' &
setsid -f runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY '/usr/local/bin/st'
runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- setsid -f '/usr/local/bin/st'

I still have to close the terminal in order to unmount the drive. I don't have any other idea, do you?

Offline

#16 2022-01-30 20:33:16

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

Offline

#17 2022-01-30 21:43:07

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

Hm, launching bash is also not helping:

runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- st -e bash

I don't have .bashrc, because I am using zsh; I've only tried this to see if it worked. Launching zsh also doesn't work.

Offline

#18 2022-01-30 21:49:45

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

The trick there was to create a transient copy of the bashrc that trails a command (in your case "cd somewhere") - something that afaics won't work w/ zsh

runuser -u $USER -w $DISPLAY,$DBUS_SESSION_BUS_ADDRESS,$XAUTHORITY -- st -e env -C /media/mounted_drive zsh

might.

Offline

#19 2022-01-30 21:55:51

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

I've tried that, unfortunately it doesn't work either.

I just got the idea that I could launch a terminal and cd into the drive with xdotool. It's quite dirty, but it would work. Or just abandon the idea altogether...

Offline

#20 2022-01-30 22:03:15

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

Doesn't work like "doesn't allow me to umount the drive w/o closing the terminal"? Could be, because the zsh process itself has still the wrong PWD.

If you're willign to touch your zshrc for this you could export some variable like "export ZSH_START_DIR=/media/mounted_drive" and in your zshrc test that variable and cd there.

[ -n $ZSH_START_DIR ] && cd $ZSH_START_DIR

Offline

#21 2022-01-30 22:41:40

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

This works fantastic! What a great idea and how simple! Thank you!!!

Offline

#22 2022-01-31 12:51:35

seth
Member
From: Won't reply 2 private help req
Registered: 2012-09-03
Posts: 77,096

Re: [SOLVED] How to launch terminal emulator from a background script?

You also want to quote the variable and tail "unset ZSH_START_DIR" to prevent it from leaking into subshells and causing unpleasant surprises.

[ -n "$ZSH_START_DIR "] && cd "$ZSH_START_DIR"; unset ZSH_START_DIR

About your latest DM: if you desperately want to donate some *really* expendable income, see https://archlinux.org/donate/ and you can also purchase merchandise, https://archlinux.org/
But I want to make clear that you're not oblieged to and you don't owe me anything - so don't touch goldmund jr.'s birthday fund tongue

Offline

#23 2022-01-31 16:46:48

goldmund
Member
Registered: 2021-02-15
Posts: 73

Re: [SOLVED] How to launch terminal emulator from a background script?

seth wrote:

You also want to quote the variable and tail "unset ZSH_START_DIR" to prevent it from leaking into subshells and causing unpleasant surprises.

[ -n "$ZSH_START_DIR "] && cd "$ZSH_START_DIR"; unset ZSH_START_DIR

Good idea, thanks!

seth wrote:

About your latest DM: if you desperately want to donate some *really* expendable income, see https://archlinux.org/donate/ and you can also purchase merchandise, https://archlinux.org/
But I want to make clear that you're not oblieged to and you don't owe me anything - so don't touch goldmund jr.'s birthday fund tongue

Your selflessness is incredible! I am going to donate to Arch Linux.

Offline

Board footer

Powered by FluxBB