3

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.

1
  • 1
    The notion of executability is of course in the eye of the beholder Commented Mar 29, 2015 at 20:36

3 Answers 3

6

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.

4
  • Thanks terdon I tried your method and it work like I wanted!
    – tony_pt
    Commented Mar 29, 2015 at 18:38
  • @tony_pt you're very welcome. If this answer solved your issue, please take a moment and accept it by clicking on the check mark to the left. That will mark the question as answered and is the way thanks are expressed on the Stack Exchange sites.
    – terdon
    Commented Mar 29, 2015 at 18:41
  • What 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
  • @HagenvonEitzen yes, that's why I clarify that this will only search for files that have the executable bit set at the end of my answer.
    – terdon
    Commented Mar 29, 2015 at 22:44
4

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.

1

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .