It looks like when adding a directory into $PATH, its subdirectories are not added recursively. So can I do that? Or is there a reason why this is not supported?
-
6Why on earth do you need that? – alex Jul 31 '11 at 07:35
-
32@alex: Why do you think there is no need? – Tim Jul 31 '11 at 11:16
-
4@Tim the reason it's not "generally" supported is it's a security risk and generally not needed. If you recursively add directories to your path who knows what might get stuck in there... makes it a lot harder to audit. – xenoterracide Jul 31 '11 at 14:44
-
4@Tim: it's a really surprising and unusual thing to want, that's why. – alex Jul 31 '11 at 15:21
-
15@alex what about for subdirectories in the bin directory? i'd love to organize scripts in directories in the bin folder. – Andy Jul 14 '14 at 15:36
-
1@alex This operation seems very natural to a beginner (who's not worrying about security). If you, say download an application in the form of a tarball that unzips to a directory, it would be easier to just add the whole directory to your path, rather than having to dig through all the subdirectories and find all the relevant executables one by one. – tparker Jul 27 '17 at 07:51
-
3@tparker A use case that may not be obvious is where one wants PATH to include a directory of user scripts, scripts so numerous that some directory organisation offers some aesthetic improvement. Anyway anyone who extracts an archive into the PATH is probably a rank beginner anyway. Those of us who work alone on single-user machines (I'm on a single-user network!) enjoy a freedom that those entrusted with high-value assets managed by multiple users and accessed by a wild and crazy public must be denied. The question is fair. No need to finger-wag. – Stephen Boston Sep 20 '18 at 18:07
-
@StephenBoston I'm afraid I don't understand your last two sentences - I agree that it's it a good question, upvoted it, and defended it against alex. Did you perhaps mean to direct your comment to alex? – tparker Sep 20 '18 at 18:45
-
@StephenBoston Ah, I think you may have misinterpreted the tone of my comment. I certainly wasn't criticizing the OP at all or suggesting that they were performing bad practice - I was actually implicitly defending them against alex's (in my opinion unhelpful and somewhat hostile) questioning. Indeed, I consider myself to be a "beginner who's not worrying about security", and could imagine using such a shortcut myself for the exact reasons you describe. Sorry if that wasn't clear. – tparker Sep 20 '18 at 18:50
-
3@tparker Oh ay. That could be. I apologise. I get overexercised by the exhortations to secure secure secure. Some people don't let their kids play outside. I think that's awful. – Stephen Boston Sep 20 '18 at 18:53
-
@StephenBoston Totally agree. Right, I was trying to give an example of a valid use case for someone who happens to not be worrying about security, with no negative judgement implied. – tparker Sep 20 '18 at 18:57
-
Having scripts readily available is very useful. They're not hidden if they're not in the PATH. Regular scripts I use either get their own alias, or I have to traverse the filesystem's path to the script, which is a huge waste of time. These scripts are called by my hands on a terminal and are written to serve me, not a complex labyrinth of calls. This question is completely justified. – Rich_F Jan 30 '19 at 11:26
-
There seems to be a very legit reason to use this: if you want to use pyreverse, you need to recursively add all subpackages (=subdirs) to the PYTHONPATH. – arne Apr 13 '21 at 19:02
7 Answers
The usual unix directory structure has application files sorted into directories by kind: bin
for executables, lib
for libraries, doc
for documentation and so on. That's when they are installed in separate directories; often applications are grouped into a few directories (hence many systems have just three directories in $PATH
: /usr/local/bin
, /usr/bin
and /bin
). It is rare to have both executable files and subdirectories inside a directory, so there's no demand for including a directory's subdirectories in $PATH
.
What might occasionally be useful is to include all the bin
subdirectories of subdirectories of a given directory in $PATH
:
for d in /opt/*/bin; do PATH="$PATH:$d"; done
However, this is rarely done. The usual method when executables in non-standard directories are to be in $PATH
is to make symbolic links in a directory in the path such as /usr/local/bin
. The stow
utility (or xstow
) can be useful in that regard.

- 2,384

- 829,060
Add them recursively using find like so:
PATH=$PATH$( find $HOME/scripts/ -type d -printf ":%p" )
WARNING: As mentioned in the comments to the question this isn't encouraged as it poses a security risk because there is no guarantee that executable files in the directories added aren't malicious.
It's probably a better solution to follow Gilles' answer and use stow
-
7Warning: This answer is technically correct but as alex and xenoterracide note this is a crazy-insecure thing to do and you should definitely think twice before actually using this. – Caleb Aug 01 '11 at 09:56
-
2Please add a warning to your answer about why this is not a good, safe thing to do in practice. – Caleb Aug 01 '11 at 09:58
-
4I wouldn't consider it particularly dangerous; adding random directories to
$PATH
is dangerous, but adding subdirectories isn't markedly worse. But it's usually useless, and possibly inefficient (and might even throw you onto environment size limits sometimes). – Gilles 'SO- stop being evil' Aug 02 '11 at 22:12 -
4@Caleb: crazy perhaps, but why insecure? If someone has access to add malicious executable files in subdirs, he could also add them to the parent dir (ie,
~/bin
or~/scripts
), so their security is the same. – MestreLion Dec 31 '15 at 12:14 -
2Security risk if you work in an environment where random people can add malicious files to your
~/scripts
. I don't and neither should anyone else – oseiskar Jul 08 '16 at 12:53 -
4@oseiskar This is completely dishonest and blatant circlejerking... Having a custom directory for scripts in your
$PATH
is something done by 99% of experienced users. Heck Ubuntu even BY DEFAULT add the~/bin
and~/.local/bin
dirs in the $PATH if they exist. Adding a single directory from the user's home in the path is absolutely not advised against. And then, if you have a single~/.local/bin
folder in your path, please explain thoroughly how you can be more at risk of malicious subverted executables with~/.local/bin/**
as opposed to~/.local/bin
only. – Atralb Nov 06 '20 at 13:17
One reason that this is not supported is because the bin/ (and similar) directories use symbolic links to point to the specific directories where actual executables for programs are installed.
So, if your $PATH
includes /usr/local/bin
(which it most likely does) that folder is full of symbolic links (like ruby
) which point to the specific directory where the code to run ruby is found (like ../Cellar/ruby/2.1.3/bin/ruby
).
This is why you don't have to specify each executable's folder in your $PATH
; the symbolic links customarily found in bin/ type directories handle that for you.
In zsh, $PATH can be appended as an array. You can use shell globbing to add multiple subdirectories to the $PATH array.
Example:
In .zshrc
:
typeset -U PATH path
BINPATH="$HOME/bin"
path+=("$BINPATH" "${BINPATH}"/*/)
export PATH
This will append all subdirectories of $BINPATH to the $PATH array.

- 31
- 2
-
1Note if you have any symbolic links in the
$BINPATH
the sub-directories will not be included. Creating a symbolic link in$HOME/bin
such asln -s $HOME/Apps
only the$HOME/Apps
base directory will be added to the path. None of the sub-directories in$HOME/Apps/
will be added. This surprised me as the/*/
implies this should work but doesn't. – RyanNerd Feb 14 '21 at 18:42
The answers didn't work for me on Mac OS, so I found a way that works:
export PATH=$PATH:$(find $HOME/apps -type d -maxdepth 1 | paste -sd ":" -)
I hope it helps!
Note: this also includes the folder itself.

- 121
@lucasls way is great and works really well, though that listed way does only work for Mac, it seems. For Linux (At least on Pop_OS 20.10 using zsh) you have to slightly rearrange things in order for it to work.
export PATH=$PATH:$(find $HOME/apps -maxdepth 1 -type d | paste -sd ":" -)
The -maxdepth is a global option and is required to be listed before the -type argument, otherwise, you end up with an error message stating as such.

- 21
- 1
Try this way:
export PATH="$PATH:$(du "~/scripts/" | cut -f2 | tr '\n' ':' | sed 's/:*$//')"
This will add ~/scripts itself along with all its subdirectories into $PATH
Explanation:
- du
will display all the subdirectories info each line
- cut -f2
will extract the second column, i.e., the names of the subdirectories
- tr '\n' ':'
will change each link break into a colon. This will join all lines into a single line and the subdirectories are delimited by a colon
- sed 's/:*$//'
will remove the last colon

- 21
-
while we are making a clear mention of scripts, that in theory should be small files, using a heavy tool like du (short for disk usage), is a poor approach; as you do pipe, cut, tr and sed, you could also start from something built to be fast and do not "be sure" about file size as the info will be tossed as ls that was built to list files; – Thiago Conrado Nov 21 '20 at 23:51