ZSH Path Source Location and Execution of a zsh script

I installed the latest Gnome version a couple of weeks ago. Noticed the changes to the terminal. I have a simple script that I created for launching Barrier KVM. It just delays it a few seconds. Changed the script from bash to zsh. It works from command line. Noticed that the path has home/user/.local/bin. But bin is missing in the home directory. So, I created it.

The script did not execute. Maybe a timing issue? That’s when I noticed the path via the terminal had duplicate entries from adding the bin directory. I then deleted the entry and the duplicate remained. Via some searching found the typeset command and removed the entry. But only for the current session.

Then started looking for the source of the path. For example in Ubuntu its the environment file. I looked everywhere and did a text search and could not find it. So the first question is where does ZSH path get set?

Second, what might the resolution be for executing the script if the location is in the path?

For now I set the path in the .zshrc file. No more double entries.

I created a .desktop file in the autostart directory to launch the script as temporary resolution.

Thanks,

Gerald

With the disclaimer that I don’t use zsh, I suspect it would be /etc/profile or possibly an additional file in /etc/profile.d/, which gets called from /etc/profile.

I’m not sure what you mean here. If an executable file is in a directory of the $PATH, then the file can be executed without the need to prefix the filename with an absolute or relative path to the file.

Thanks for the reply. I’ve never used ZSH before either. Hence the questions on how it works. Apple just switched over to ZSH. I expect Manjaro to implement across other DT environments in the future.

I did a content search in etc. Nothing found. I then did a search over the entire drive. Some files came back not permitted. Then I physically checked all those locations and more. No path in text format found. Its really fascinating. Read the manual too. Its really long and involved. But nothing about the path source. Watched some youtube videos on ZSH to see what can be done with it. No one mentions the location of the path source.

I’ll keep looking until I find it.

The zsh script would not execute upon boot up and login. So I removed the path entry by editing the path I created in .zshrc which apparently overwrites the original source of unknown location thus far.

As I mentioned the script works with the location of the script in the path by simply executing it via the command line. Just the name of the script from any directory as one would expect.

why you have a zsh script ?
I use zsh but use bash scripts, zsh is only for the user shell

for path we have some origins (last is .bashrc or .zshrc, before profile and for me kde also sddm.conf)

how to you run this script ? systemd … .config/autostart ?

Myself, I use bash as my interactive shell, but I write my scripts in strict POSIX-compatible Bourne shell code.

#!/bin/sh

:wink:

1 Like
ls -l /bin/sh
lrwxrwxrwx 1 root root 4 10 juil. 18:57 /bin/sh -> bash

Yes, but bash behaves differently when it is called as sh. Then it won’t interpret any “bashisms” and it’ll stick to strict Bourne syntax. :wink:

The current cool kids use env

#!/usr/bin/env

sure ? echo “${v/to/ta}” is not posix

same result:

/bin/bash -c 'echo ${1:-toto}; v="toto"; echo "${v/to/ta}" '
toto
tato
[ssd-manja ~]# /bin/sh -c 'echo ${1:-toto}; v="toto"; echo "${v/to/ta}" ' --posix
toto
tato

and if i create a script .sh with #!/usr/bin

as [[ ]] is not posix but:

$ /bin/sh --posix -c ' [[ -n $HOME ]] && echo "is set" ' --posix
is set

sorry it’s not zsh !

If Bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

Source here.

:slight_smile:

1 Like

I tried using .sh script at the beginning. But just to make sure because I’m prone to making mistakes when spending two days trying to get something to work I added the path for the home directory where the script is located and changed it from .zsh to .sh format. Logged out and back in and it failed to execute.

The reason I chose to make the script zsh was because I could check it out using the terminal.

Here it is as bash.

#!/bin/bash
sleep 5
/usr/bin/barrier&
exit

bash shell and zsh use only shebang (first line in script), file extension doesn’t matter :wink:

good script (if barrier exists) is

#!/bin/bash
sleep 5
/usr/bin/barrier &
2 Likes

That doesn’t make any difference, because a script is always executed in a subshell, even if you launch it from the command line.

The only times a script is not executed in a subshell are when…

  • the script is sourced instead of executed, in which case the commands in the script are run in the current shell; and/or
  • the script is invoked with exec, in which case it replaces the running shell in the process tree.
2 Likes

yeah … it says that … but years of experience say it isnt a drop-in replacement.

3 Likes

Not as such, no, but you can add additional invocation parameters to make it strictly POSIX-compliant.

But even then still, that’s not what bash was designed for. It has additional features that were intended to be used, and that either extend and/or alter basic Bourne and POSIX functionality.

The reason why I write my scripts as strictly Bourne- and POSIX-compliant is so that they would be portable.

2 Likes

The alter part is my main concern.
You can have a fancy prompt with BASH.
You can do things like Ctrl+R for dynamic history … etc.
zsh is a different platform. linux is built with bash. I think its about as simple as that.

3 Likes

You don’t have to change your script - just use it as is with the bash shebang.

We used to have a guide to barrier on Manjaro


And the long conversation of bash vs sh vs zsh is off topic for the current thread.

Any views expressed is the member’s personal view.


zsh sources /etc/profile (from /etc/zsh/zprofile) and your local .profile which is where per user options is set.

Just noted the question on ~/.local/bin.

This is added to the path whether it exist or not. This is done in the file /etc/profile.d/home-local-bin.sh which is sourced by the shell.

The folder ~/.local/bin is part of systemd specification - on some editions the folder is created by adding it inside the /etc/skel/ folder - on others it is not. This is depending on the maintainer.

$ systemd-path user-binaries
1 Like

Thanks linux-aarhus. So far I checked etc/profile.d. Of all the bash scripts in that directory "home-local-bin.sh is set to execute. So that takes care of the ~/.local/bin. "gpm.sh references disable-paste is set to execute. “locale.sh” references language and locations is set to execute.

I saw the zprofile which refers to /etc/profile which does not exist in etc.

So at this juncture I can’t find the balance of the path /usr/local/bin:/usr/local/sbin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin"

There is a “perlbin.sh” in profile.d but it is not set to execute. Neither is “snapd.sh” set to execute.

As for the zsh or sh script I created in the home directory it does not execute with the path set to that directory. But it does execute using a .desktop file in autostart that calls the script both as a zsh or sh.

Thanks,
Gerald

For what I know - all Manjaro ISO installs /etc/profile - if you don’t have this?

This is the default /etc/profile found on any Manjaro system

# /etc/profile

# Set our umask
umask 022

# Append "$1" to $PATH when not already in.
# This function API is accessible to scripts in /etc/profile.d
append_path () {
    case ":$PATH:" in
        *:"$1":*)
            ;;
        *)
            PATH="${PATH:+$PATH:}$1"
    esac
}

# Append our default paths
append_path '/usr/local/sbin'
append_path '/usr/local/bin'
append_path '/usr/bin'

# Force PATH to be environment
export PATH

# Load profiles from /etc/profile.d
if test -d /etc/profile.d/; then
	for profile in /etc/profile.d/*.sh; do
		test -r "$profile" && . "$profile"
	done
	unset profile
fi

# Unload our profile API functions
unset -f append_path

# Source global bash config, when interactive but not posix or sh mode
if test "$BASH" &&\
   test "$PS1" &&\
   test -z "$POSIXLY_CORRECT" &&\
   test "${0#-}" != sh &&\
   test -r /etc/bash.bashrc
then
	. /etc/bash.bashrc
fi

# Termcap is outdated, old, and crusty, kill it.
unset TERMCAP

# Man is much better than us at figuring this out
unset MANPATH

And your thoughts on execution - if a shell script is sourced - it don’t need the execution bit to actually work - the execution is maintained by the script sourcing the file.

No, I don’t have the /etc/profile.

When I created the bin directory as listed in the path I got a duplicate entry. I just returned the system back to the original path by removing mine in .zshrc. So here is what it looks like now with the duplicate entries. I can remove them using “typeset -aU path”. But that only lasts for the current session. So, far have not found a way to return the system back to the default path as installed and last past one session.

PATH="/home/gerald/.local/bin:/home/gerald/.local/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/var/lib/snapd/snap/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl"