I am writing a few bash scripts and need some assistance with being able to find an executable file within a directory and assigning it to a variable.

so I know if I run:

ls -dF `find . -maxdepth 1 \( -perm -1 -o \( -perm -10 -o -perm -100 \) \) -print`

it will return something like this:


What I would like to do is have it return:


and then have something like:

coind='ravend' coincli='raven-cli'

I am assuming I would have to do something like this code example, but i just don't know how to write it

output=$(ps -ef | awk '/siebsvc –s siebsrvr/ && !/awk/ { a++ } END { print a }'); echo $output

I would say doing something generic to get multiple results, and then using parts of that result to specific things is not a good idea. I would suggest doing a more targetd search for each of the variables.

Disregarding this, I had fun coming up with the following solution:

#!/usr/bin/env bash

main() {
    local coind coincli
    read -a executables -r < <(find . -maxdepth 1 -type f \( -perm -1 -o \( -perm -10 -o -perm -100 \) \) -printf "%f ")

    (( "${#executables[@]}" > 2 )) && { echo "Found more than 2 executables: ${executables[*]}"; return 1; }

    local word
    word="$(comm -12 --nocheck-order <(grep -o . <<<"${executables[0]}") <(grep -o . <<<"${executables[1]}") | awk '{printf $0}')"

    for executable in "${executables[@]}"; do
        local variable="${executable/${word}/coin}"
        declare "${variable}=${executable}"

    echo "coind: ${coind}"
    echo "coincli: ${coincli}"

main "$@"
exit $?

find . -maxdepth 1 -type f \( -perm -1 -o \( -perm -10 -o -perm -100 \) \) -printf "%f " - find files with executable permission in current directory, and only print file name (no path)

comm -12 --nocheck-order <(grep -o . <<<"${executables[0]}") <(grep -o . <<<"${executables[1]}") - find the word/characters that exist in both executable names

grep -o . <<<"${executables[0]}" - split string into 1 character per line (done for both executables)

| awk '{printf $0}') - each character is printed on a new line, this is used to collapse it into a word

variable="${executable/${word}/coin}" - replace (once) the common word with coin (will be used to set the variables later)

variable="${variable//[^a-z]/}" - remove all characters that isn't anything of a through z (in this case, remove - from the variable name

declare "${variable}=${executable}" - dynamically declare variable and set it's value.

  • This is awesome! Thank you. I ran a couple of tests and this is getting me where I want to be. Question though, there will not always be a -cli executable file though. When I ran this with both files in the directory it worked flawless. When I ran it with the -cli file removed it returned nothing for both variables. – jonathan adams Sep 21 '18 at 13:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.