Under ~/Pictures there are some sub-directories containing jpegs like ~/Pictures/Pics 1/img.jpg.

From bash:

~/Pictures $ `file Pics\ 1/img.jpg`   


Pics 1/img.jpg: JPEG image data, Exif standard:: [TIFF image data,
little-endian, direntries=12, description=....

I create script.sh and chmod a+x

VAR=$(builtin printf "%q" "$1")
CMD="file $VAR"
EXIF=eval "$CMD"
echo "$EXIF"
~/Pictures $ ./script.sh Pics\ 1/img.jpg


./script.sh: line 4: file Pics\ 1/img.jpg: No such file or directory

Also tried full path for img.jpg and /usr/bin/file

OS: Raspbian updated/upgraded
I've read several similar questions/answers and didn't get the key

EDIT: Maybe it would be useful for someone to use exiftool instead of file
Because of locale issue I posted as a comment in the answer marked as solution (and because I get more info) I am going to use exiftool.

COMM="/usr/bin/exiftool -Description \"$1\""    
DESCR=$(eval "$COMM")    
DESCRIPTION=${DESCR#"Description                     : "}

It outputs correctly the metatada Description with special characters


There's no need to try to be smart with quoting in the script. Just make sure that you double quote the expansion of $1 (and any other variable):


exif=$( file "$1" )
printf '%s\n' "$exif"

or just


file "$1"

To run:

./script.sh Pics\ 1/img.jpg


./script.sh "Pics 1/img.jpg"


./script.sh "Pics 1"/img.jpg

What happens in your script is that you make the \ part of the pathname. It's not part of the pathname, it's just there to escape the space on the command line.

Also, you are assigning the string eval to the environment variable EXIF for the duration of the file command. You probably meant EXIF=$( eval "$CMD" ), but this is not needed (see above).

If you really wanted to store the full file command in a variable, you should be using an array:


cmd=( file "$1" )
exif=$( "${cmd[@]}" )
printf '%s\n' "$exif"

Again, no need for eval here.

... not even if we write it for /bin/sh (which does not have arrays, but that does have the list of positional parameters, also available in bash obviously):


set -- file "$1"
exif=$( "$@" )
printf '%s\n' "$exif"
  • That simple. I already had started in that way. I don't exactly recall why I did get a 'not found' error msg because of the blank not escaped. I believe that time I mixed sh and bash, I should have executed ./script.sh instead of sh script.sh. There are times that it would easy to clean all and start over. Thank for the plus, next step, building the array. – dstonek May 22 at 16:25
  • From the file output: "description=" I get \303\251 instead of é. I added LC_ALL=es_UY.UTF-8 to the script but nothing changes – dstonek May 22 at 19:42
  • @dstonek You would have to export the LC_ALL variable in the script, or it will not be seen by file. – Kusalananda May 22 at 19:43
  • I already did that, I forgot to add export in the last comment. Added after #!/bin/bash – dstonek May 22 at 19:46
  • @dstonek You may want to ask a completely new question about this specific issue. I'm not very good with locale-related issues. – Kusalananda May 22 at 19:48

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.