I have a directory with code files and executable files and I want to know how to create a symbolic link only to executable files in that directory?
I know that path-of-directory/*
selects all files however I only want the executables.
I have a directory with code files and executable files and I want to know how to create a symbolic link only to executable files in that directory?
I know that path-of-directory/*
selects all files however I only want the executables.
You can use find
to list executable files:
find /foo -type f -executable
You can then use the -exec
option to create the link.
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of `;' is encountered. The string `{}'
is replaced by the current file name being processed everywhere
it occurs in the arguments to the command [...]
So, to create a link in ~/bar
to each executable file in ~/foo
, you would do
find ~/foo -type f -executable -exec ln -s {} ~/bar \;
Note that this is not searching for binary files, simply for those that have the executable bit set.
man find
says about -executable
: "Because this test is based only on the result of the access(2) system call, there is no guarantee that a file for which this test succeeds can actually be executed". However this caution is probably irrelevant for Joe averages files on a local disk.
Commented
Mar 29, 2015 at 20:34
Another possibility:
for i in ~/foo/*; do [ -x "$i" ] && ln -s "$i" ~/bar; done
-x
tests if the file exists and is executable. See man test
for more information.
If you want to create working relative links you might need to think about how you provide your directory paths, or use the -r
option to ln
(which is a somewhat new GNU extension (≥ 8.16), but should be present in all "recent" distributions).
If you want to traverse into subdirectories using this method, activate globstar
with shopt -s globstar
and give the search path as ~/foo/**
(see globstar
in the Bash manual).
The [ -x ]
test will include directories with the executable bit set, which might not be wanted. If it is a problem, an extra [ -f ]
test to see if the match is a file can be added.
If you use zsh (and I recommend trying it for magic like this), you can simply use a glob qualifier.
ln -s /path/to/foo/*(*) /path/to/bar
(*)
means just executable files; you can use similar constructions for files, directories, links, etc. or even more advanced sorting and manipulation operations.