1

I created a function to list filenames in a directory. I have to do this without using ls.

#!/bin/bash

function myfind(){
    local directory=$1
    echo "$(directory)"
    for file in "$(directory)"/*;
    do
        if [[ -d "${file}" ]];
        then
             myfind "$file"
        else
            echo "(basename "${file}")"
        fi
    done
}
    

when I try to call the function it just states command not found. If I try to make it an executable (which I know is most likely wrong) it won't perform anything. Any help would be greatly appreciated.

LRJuarez
  • 29
  • 2
  • BTW, leave out the `function` -- `function myfind() {` merges the legacy ksh syntax `function myfind {` and the POSIX sh syntax `myfind() {` in a way that's incompatible with _both_ legacy ksh and POSIX sh. See also https://wiki.bash-hackers.org/scripting/obsolete – Charles Duffy Mar 15 '23 at 05:00
  • And `"$(directory)"` is trying to run `directory` as a command, which it isn't, so it's correct to be not found. You want `echo "$directory"` – Charles Duffy Mar 15 '23 at 05:01
  • @CharlesDuffy I suggest closing this question with this [question](https://stackoverflow.com/questions/17992711/brackets-difference-and-usage-in-bash). It seems more relevant. – unrealapex Mar 16 '23 at 17:37

2 Answers2

1

The problem with your shell script is you attempt to reference the $directory variable using command substitution $() instead of variable referencing $.

Also, the program basename already sends its output to stdout so there is no need to send the output to echo.

#!/bin/bash

myfind() {
    local directory=$1
    echo "$directory"
    for file in "$directory"/*;
    do
        if [[ -d "${file}" ]];
        then
            myfind "$file"
        else
            basename "${file}"
        fi
    done
}

edit: forgot to add and as Gordon Davisson suggested, do not use the function keyword, it is not needed in Bash.

unrealapex
  • 578
  • 9
  • 23
1

I think you're mixing up your shell expansions, specifically ${ } and $( ). They look similar, but do completely different things, and it's important to use the right one for the job. $( ) does command substitution -- it runs what's inside the $( ) as a shell command, captures its output, and basically inserts it into the command line at that point. ${ }, on the other hand, treats what's inside it as a variable or parameter name (maybe with some modifiers attached), and inserts its value.

So when you use "$(directory)", the shell tries to run directory as a command. But it's not a command, it's a variable, so that fails and you get a "command not found" error. You want "${directory}" (or just "$directory", since this is one of the simple cases where `{} is optional).

Also, in the line

echo "(basename "${file}")"

...there's no $ before (basename, so it's not treated as any sort of expansion, just a plain string. You want "$(basename...)", except that (as UnrealApex pointed out) the echo and the "$( )" are basically cancelling each other out, and you should just omit both. So just use:

basename "${file}"

One more recommendation: the function keyword is nonstandard and unnecessary. I recommend just starting function declarations like this:

myfind() { ...

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151