You are not logged in.

#1 2015-06-07 13:22:05

Lerp
Member
Registered: 2014-03-05
Posts: 35

[Solved] User scripts not being detected by xinitrc or dmenu

I have a folder in my home directory where I put scripts. This folder is on the PATH environment variable but they are not being picked up by dmenu or being executed when called from my xinitrc. I can however call them from the terminal.

I add the folder to my PATH on my zshrc (int he vars section):

# Options
HISTFILE=~/.histfile
HISTSIZE=1000
SAVEHIST=1000

setopt noflowcontrol
setopt appendhistory extendedglob
setopt promptsubst
unsetopt beep nomatch notify

# Keybindings
typeset -g -A key

bindkey '^?'    backward-delete-char    # Backspace
bindkey '^[[2~' overwite-mode           # Insert
bindkey '^[[3~' delete-char             # Delete
bindkey '^[[7~' beginning-of-line       # Home
bindkey '^[[8~' end-of-line             # End
bindkey '^S'    insert-sudo

# Vars
export EDITOR="gvim"
export JAVA_HOME=/usr/lib/jvm/java-7-jdk/jre/
export USER_SCRIPTS=$HOME/dotfiles/scripts
export PATH=$PATH:$USER_SCRIPTS
export _JAVA_OPTIONS='-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true -Dswing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel'

# Colours
export WHITE=#C5C8C6
export BLACK=#1D1F21
export DARK_GRAY=#373B41
export LIGHT_GRAY=#969896
export RED=#CC6666
export ORANGE=#DE935F
export YELLOW=#F0C674
export GREEN=#B5BD68
export AQUA=#8ABEB7
export BLUE=#81A2BE
export PURPLE=#B294BB

# Prompt
autoload -U colors && colors

coloured() {
    local c='black'

    if [[ $# -ge 2 ]]; then
        c=$2
    fi

    echo "%{$fg_bold[$c]%}$1%{$reset_color%}"
}

local user_host="%n$(coloured '@')%m"
local current_dir=" %~ "

PROMPT="╭─${user_host}${current_dir}
╰─$ "

# Misc
# Function for inserting sudo at the start of the line
insert_sudo() {
    if [[ $BUFFER != "sudo "* ]]; then
        BUFFER="sudo $BUFFER"
        CURSOR+=5
    fi
}

zle -N insert-sudo insert_sudo

# Hooks
source /usr/share/doc/pkgfile/command-not-found.zsh

My xinitrc calls a script in USER_SCRIPTS called panel:

#!/bin/zsh

if [ -d /etc/X11/xinit/xinitrc.d ]; then
    for f in /etc/X11/xinit/xinitrc.d/*; do
        [ -x "$f" ] && . "$f"
    done

    unset f
fi

sxhkd &
panel &

exec bspwm

But this script isn't called. My guess is xinitrc is loaded before zshrc but that doesn't answer the dmenu issue.

How can I add my user scripts folder to my path such that xinit and dmenu detect the scripts?

Last edited by Lerp (2015-06-08 02:54:34)

Offline

#2 2015-06-07 13:38:56

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

Re: [Solved] User scripts not being detected by xinitrc or dmenu

Lerp wrote:

My guess is xinitrc is loaded before zshrc but that doesn't answer the dmenu issue.

Yes it does - if dmenu is launched from a WM keybinding.

Set the path higher in the hierarchy, like in your shell profile which is recommended anyways.  To prove to yourself that it will work, you can set (and export) the new path right before tying xinit/startx, and everything should work as intended for that session.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2015-06-07 20:58:09

Lerp
Member
Registered: 2014-03-05
Posts: 35

Re: [Solved] User scripts not being detected by xinitrc or dmenu

Trilby wrote:
Lerp wrote:

My guess is xinitrc is loaded before zshrc but that doesn't answer the dmenu issue.

Yes it does - if dmenu is launched from a WM keybinding.

Set the path higher in the hierarchy, like in your shell profile which is recommended anyways.  To prove to yourself that it will work, you can set (and export) the new path right before tying xinit/startx, and everything should work as intended for that session.

dmenu is being launched from a WM keybinding, why does that mean it doesn't detect the extended path? (I'm not disputing your point just curious)

I have moved the USER_SCRIPTS and PATH definitions to my .profile, is this the correct place? From what I read /etc/profile and .profile are the shell profiles but one's local and one's local?

Last edited by Lerp (2015-06-07 21:09:26)

Offline

#4 2015-06-07 21:21:16

Head_on_a_Stick
Member
From: London
Registered: 2014-02-20
Posts: 7,732
Website

Re: [Solved] User scripts not being detected by xinitrc or dmenu

Lerp wrote:

dmenu is being launched from a WM keybinding, why does that mean it doesn't detect the extended path?

Because you are setting your new $PATH in a configuration file for an *interactive* shell and dmenu is not being started from such a shell.

You should set $PATH from a configuration file for a *login* shell so the variable is set when you start the X server and inherited by all subsequent processes.
https://wiki.archlinux.org/index.php/Ba … tion_files

So yes, ~/.profile would be correct as this is a configuration file for both interactive *and* login shells.

EDIT: Many typos...

Last edited by Head_on_a_Stick (2015-06-07 21:35:37)

Offline

#5 2015-06-07 21:37:13

Raynman
Member
Registered: 2011-10-22
Posts: 1,539

Re: [Solved] User scripts not being detected by xinitrc or dmenu

Head_on_a_Stick wrote:

So yes, ~/.profile would be correct as this is a configuration file for both interactive *and* login shells.

Except that Lerp seems to be using zsh, which only reads ~/.profile in compatibility mode.

See "Startup/shutdown files" in the man page.

Offline

#6 2015-06-07 22:35:25

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

Re: [Solved] User scripts not being detected by xinitrc or dmenu

Actually my point had nothing to do with the type of shell (interactive or not, login or not, etc).  Environment variables are only set within one environment, and environments are inherited.  This is a very common misunderstanding of environment variables.  You can set it in your terminal, but that will not affect anything but that terminal instance and anything launched from within that terminal.

Did you run the test I suggested?  If you do, you will set (and export) the PATH environment variable before calling startx.  Then xinit inherits that environment variable, so it can be used.  Further the window manager inherits that environment variable, as do any subprocesses started by the WM (like dmenu).

In contrast, if you set the path in your shellrc, and you 'exec' xinit/startx from your shellrc before the PATH is set, then xinit will not inherit the variable, so the xinitrc scripts fail.  Then once in X you open a terminal, in this terminal you set and export PATH - but this only sets the variable for that terminal's environment and any of it's children.  When you launch dmenu from a key binding, dmenu inherits the WM's (and xinit's) environment which lacked the new PATH variable so your scripts are not found.  But if you launch dmenu from within that terminal in X, that instance of dmenu inherits from the terminal and has the new path variable and your scripts will work.

In short, login/not-login, interactive-not-interactive is irrelevant (except it determines which files are read).  Just be sure to set and export the PATH from somewhere higher in the process hierarchy than where you want to use it.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#7 2015-06-08 01:22:52

Lerp
Member
Registered: 2014-03-05
Posts: 35

Re: [Solved] User scripts not being detected by xinitrc or dmenu

I believe I understand now, dmenu inherit's the window manager's environment which inherits X's environment. In none of those environments has my PATH been extended. When I call it from my terminal the terminal exists in a different environment where the PATH has been extended to include my user scripts.

I tried setting the variables in ~/.profile, this didn't work for two reasons: I'm using zsh so the correct file would have been ~/.zprofile and secondly I'm assuming it's too low in the hierarchy as when I tried ~/.zprofile it did not work. I bumped it up a level to /etc/profile which worked but there were two issues.

The first issue is that the scripts were still not on dmenu's PATH, they did however make there way onto X's environment as xinitrc successfully called my user scripts. I'm not sure what's happening there as from my understanding dmenu should be inheriting X's environment vicariously through the window manager? I thought maybe dmenu uses a different variable but reading dmenu's man page it does say it lists programs on the PATH variable.

The second issue is that the scripts called by ~/.xinitrc which rely on the colour environment variables set in my ~/.zshrc. I like to keep my colours in environment variables so the colours are easily changed and remain consistent throughout my scripts. I assume this could be easily solved by moving the colours up a level to /etc/profile. That solution however seems a bit brutish. My understanding is that /etc/profile is a global configuration, so if there were a second user on my system and I had set the colours inside of that file they would be forced upon that second user.

I looked at the wiki to try and determine a fitting local configuration file. Reading /etc/profile shows that we cannot set the PATH variable anywhere higher in the hierarchy as it overwrites the PATH. The next local configuration is .zprofile which has already been tested and did not work. The only solution I can see is to modify /etc/profile to not overwrite the path if it is not empty. User configuration can then be put in the user's ~/.zshenv which is a local file higher up in the hierarchy, according to the wiki.

Offline

#8 2015-06-08 01:27:37

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

Re: [Solved] User scripts not being detected by xinitrc or dmenu

PATH makes sense to put in /etc/profile (in many cases) but I wouldn't start putting much else there.  Just make sure it is before xinit is called.  How do you start x?  If you call xinit or startx from a tty manually, this problem shouldn't exist.  If you autostart xinit/startx from a shellrc file, then you can just move some of the bits you want included above the `exec startx` line.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#9 2015-06-08 02:04:29

Lerp
Member
Registered: 2014-03-05
Posts: 35

Re: [Solved] User scripts not being detected by xinitrc or dmenu

I'm not sure where startx is called from. Best I can discern is in my SLiM config file (/etc/slim.conf) the following line:

login_cmd /bin/zsh --login ~/.xinitrc %session

---

I went ahead and tried my solution in the previous post. I modified the lines of my /etc/profile that sets the PATH to below:

# Set our default path if it is not set already
if test ! $PATH; then
	export PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
fi

And set the PATH in ~/.zshenv. This worked perfectly except for it appears to be called multiple times as my PATH variable is now getting repeats and dmenu still refuses to detect my user scripts:

╭─james@pc ~ 
╰─$ echo $PATH
/bin:/usr/bin:/usr/local/bin:/home/james/dotfiles/scripts:/usr/share/java/gradle/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/james/dotfiles/scripts:/home/james/dotfiles/scripts

I'm guessing each new environment is calling ~/.zshenv, and each time ~/.zshenv extends the path with /home/james/dotfiles/scripts?

---

I fixed the repeated entries by adding a condition in my ~/.zshenv such that it only extends the path if $USER_SCRIPTS is not currently on the path:

if test ! -z "${PATH##*$USER_SCRIPTS*}"; then
    export PATH=$PATH:$USER_SCRIPTS
fi

In regards to dmenu it appears that it is using the extended path just dmenu is not offering the user scripts in the autocomplete. This was resolved by deleting the dmenu cache:

rm ~/.cache/dmenu_run

Last edited by Lerp (2015-06-08 02:53:19)

Offline

Board footer

Powered by FluxBB