1

I have been trying to get this to work for a while now, and I am still confused as to why it doesnt work. I'm trying to add a function to my bashrc to cd down to the next directory that has files or more than one directory in it. But I cant get this test for files to work, and I do not understand the problem. find . -maxdepth 1 -type f works when I type it into the terminal, but here it doesn't seem to be working. And -z should test if it is null, which it should be when Icall it in an empty directory. But it just returns files detected every time... is it the use of the dot operator in doFilesExist?

function cdwn(){
    # check if there are files or multiple directories in current wd
    doFilesExist="find . -maxdepth 1 -type f"
    if [ -z '$doFilesExist' ]; then
        echo "no files  detected"
    else
        echo "files detected"
    fi
}

Thanks guys, seems to be working with the following:

function cdwn(){
    # check if there are files or multiple directories in current wd
    doFilesExist=`find . -maxdepth 1 -type f`
    if [ -z "$doFilesExist" ]; then
        echo "no files  detected"
    else
        echo "files detected"
    fi
}

But I am not satisfied as I do not understand why I was having problem, can you suggest some guides I can follow to get a better understanding? I clearly have either forgotten or not understood things in the past!

user122072
  • 91
  • 1
  • 8
  • `[ -z $var ]` checks if the variable `var` is set or not. In your case there's a string in `var` so it is always set. -- BTW add double quotes when using unary comparison (`[ ... ]`). – ShellFish Apr 11 '15 at 23:02
  • ... so you need double quotes to have the value of `$doFileExist` interpreted, otherwise it will just check if the string `$doFilesExist` instead of its value: `[ -z "$doFilesExist" ]` – fedorqui Apr 11 '15 at 23:03
  • By the way, instead of editing the post saying "hey this works" you can [also] mark as accepted the answer that solved your issue. This way it is clear to future visitors that your problem is solved to future readers – fedorqui Apr 11 '15 at 23:09
  • 1
    sorry about that, I will make sure to select an answer in future – user122072 Apr 11 '15 at 23:23

2 Answers2

1

Looks like wrong quotes. To put a result of bash command to a variable:

doFilesExist=$(find . -maxdepth 1 -type f)

or

doFilesExist=`find . -maxdepth 1 -type f`

The part with if block should be also changed to [ -z "$doFilesExist" ]: "Inside a single-quoted string nothing(!!!!) is interpreted, except the single-quote that closes the quoting" source.

idobr
  • 1,537
  • 4
  • 15
  • 31
  • 1
    In fact you could just say `if [ -z "$(find ... )" ]`, no need to use the variable. – fedorqui Apr 11 '15 at 23:13
  • Haha, that's a nice one! Might become unreadable but this is definitely one of the shortest find commands I've ever seen. So no problem there. – ShellFish Apr 11 '15 at 23:18
  • In fact, yes. I've marked places to rewrite. Your advice is a good step further. To understand, who it works, you can read about [Command substitution](http://wiki.bash-hackers.org/syntax/expansion/cmdsubst). – idobr Apr 11 '15 at 23:20
1

You should try the following:

function cdwn(){
    # check if there are files or multiple directories in current wd
    files=$(find . -maxdepth 1 -type f | wc -l)
    if [[ ${files} -gt 0 ]]; then
        echo "files detected"
    else
        echo "no files detected"
    fi
}

Don't check using -z as it checks if a variable is set or not, it says nothing about the size. Also you just stored a command as a string, it has never been executed. To execute it you could store the content in a variable like some of the other answers suggest but those variables could become incredible large.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
ShellFish
  • 4,351
  • 1
  • 20
  • 33
  • it is a bit overkilling to write into a file – fedorqui Apr 11 '15 at 23:08
  • As opposed to putting it all into a variable? – ShellFish Apr 11 '15 at 23:11
  • Yep. Writing into a file means using disk, etc, whereas a variable is way more quickly accessible. Also, you never know if you can write in any given directory (for example, what if you are executing this in /etc not being root?) – fedorqui Apr 11 '15 at 23:12
  • 1
    Well maybe it is, I'll remove this answer probably. – ShellFish Apr 11 '15 at 23:14
  • Thanks for pointing that out, I will not ignorantly stand my ground, haha – ShellFish Apr 11 '15 at 23:14
  • No problem, it is all about learning here :) and of course, about trying and seeing what happens with one or another approach, so it is good that you posted the answer! – fedorqui Apr 11 '15 at 23:15
  • What do you think about this approach? – ShellFish Apr 11 '15 at 23:16
  • 1
    Well it is interesting but not very much the way I would do it. Note that counting the number of results of `find` piping to `wc -l` can lead to errors if some file names contain new lines (it is weird but it can happen!). But in this case it helps, yes. I would in fact just say `if [ -z "$(find ...)" ]` to get rid of variables and everything. – fedorqui Apr 11 '15 at 23:19
  • Finally, see a very nice approach for this: [How to tell if the output of the “find” command is empty?](http://stackoverflow.com/a/6527475/1983854). Quitting after the first match is a beautiful way to optimize the command! – fedorqui Apr 11 '15 at 23:21
  • Yes I was trying to achieve that but failed, I tried some hacky stuff by using `-exec` combined with a variable being set and quitting to no luck. But thanks for that link, I should have googled first (when will I learn)! – ShellFish Apr 11 '15 at 23:23
  • I didn't know about the `-quit` option either, it was a nice discovery I just did. Probably you were using `-exec` and then some stuff, but the variable you were setting was being distroyed after each iteration since it opens a subshell every time – fedorqui Apr 11 '15 at 23:26
  • 1
    Yes exactly, and since it's a subshell exporting didn't help either. So basically I had to resort back to writing to a file, which kind of completes the circle, haha. Anyway, thanks for the tips and pointers, it's always nice to learn! – ShellFish Apr 11 '15 at 23:31