Why doesn't the conditional work when I use it directly without a variable?

Couple of issues:

  • ] indicates the end of arguments for [ (test), and it must be the last argument; you have couple of ]s, which is wrong; presumably you meant to use:

    if [ $( file -b $i ) == "directory" ]
  • If you had used the above, you would get bash: [: too many arguments, because word splitting would be done upon on the output of the variable expansion ($i), and then command substitution, $() (file command) and [ will see multiple words before =, leading to the error message. You need to quote the variable expansion, and command substitution:

    [ "$(file -b "$1")" == "directory" ]

As a side note, you should use the bash keyword [[, instead of [ as the former will handle word splitting (and pathname expansion) for you.

if [ $( file -b $i ) == "directory" ]

Two issues here:

  • Use single = for string comparison. See man test for proper syntax( note, that [ in many cases has shell-specific implementation, so see your shell's man page if you don't have documentation for test). If you absolutely need == , use [[ instead, which is feature of many bourne-like shells, including bash,ksh,zsh. NOTE: while == exists in bash since version 2.0, " = should be used with the test command for POSIX conformance." ( bash man page).

  • Quote all your variables as "$()" . Specifically of interest is $i. Filenames with space will break $i into multiple words due to shell's word expansion.


bash-4.3$ mkdir with\ space
bash-4.3$ i="./with space"
bash-4.3$ set -x
bash-4.3$ [ $( file -b $i ) == "directory" ] && echo "YES"
++ file -b ./with space
+ '[' cannot open '`./with'\''' '(No' such file or 'directory)' cannot open '`space'\''' '(No' such file or 'directory)' == directory ']'
bash: [: too many arguments

name=$( file -b $i )
if [ name == "directory" ]

Issues here:

  • name is not expanded to variable, it's just a string "name" here. You need "$name" and again, single =

Also, it cannot have possibly have worked , since exit status of test is returned as false ( exit status 1)

$ name=$(file -b /etc)
$ set -x
$ [ name == "directory" ]
+ '[' name '==' directory ']'
$ echo $?
+ echo 1

The above tested on bash and mksh shells.

There are lots of issues! Let’s take this part which is "working":

 name=$( file -b $i )
 if [ name == "directory" ]

This assigns the output of the file command to the variable called name, but doesn't use it; instead, it runs the [ command with 3 parameters: name, ==, and directory. Accepting == is a bash extension.

If this was corrected to use $name rather than name you would again get a too many arguments problem for many cases. This is because file returns multiple word results like ASCII text. So after the command has run you get

if [ ASCII text == directory ]

and now it is obvious that the command is missing some grouping.

if [ "$(file -b -- "$i")" = "directory" ]

is probably what you want: = rather than == for portability, and quoting the result of command substitution which you almost always want to do.