I want to copy executable files from one directory to another.
The source directory includes all sorts of files I don't care about (build artifacts). I want to grab only the executable files, using a bash script that works on both OS X and Linux.
By executable, I mean a file that has the executable permission, and would pass test -x $filename
.
I know I can write some python script but then I would be introducing a dependency on python (just to copy files!) which is something I really want to avoid.
Note: I've seem a couple of similar questions but the answers seem to only work on Linux (as the questions specifically asked about Linux). Please do not mark this as duplicate unless the duplicate question is indeed about cross platform copying of executable files only.
Your own answer is conceptually elegant, but slow, because it creates at least one child process for every input file (test
), plus an additional one for each matching file (cp
).
Here's a more efficient bash
alternative that:
cp
.#!/usr/bin/env bash
exeFiles=()
for f in "$src_dir"/*; do [[ -x $f && -f $f ]] && exeFiles+=( "$f" ); done
cp "${exeFiles[@]}" "$dest_dir/"
exeFiles=()
initializes the array in which to store the matching filenames.for f in "$src_dir"/*
loops over all files and directories located directly in $scr_dir
; note how *
must be unquoted for globbing (filename expansion) to occur.
[[ -x $f && -f $f ]]
determines whether the item at hand is executable (-x
) and a (regular) file -f
; note that double-quoting variable references inside [[ ... ]]
is (mostly) optional.exeFiles+=( "$f" )
appends a new element to the array"${exeFiles[@]}"
refers to the resulting array as a whole and robustly expands to the array elements as individual arguments - see Bash arrays.