1

Hello i have the following problem: This code is runing in a shell-script without syntax error on my pc but on an other server i get a syntax error "(" unexpected

export data=( $(find "~/" -iname "*.png") )
for i in ${data[@]}
do
    mogrify -crop 1024x794 ${i}
    rm ${i%.png}-1.png
    mv ${i%.png}-0.png ${i}   
done
5
  • 1
    Not that this isn't safe for paths/files with spaces in them. Also a quoted ~ doesn't get expanded correctly so this can't be working at all as written here. And you don't need (or want) export here. Commented Jan 20, 2016 at 14:33
  • 1
    This is basically mywiki.wooledge.org/DontReadLinesWithFor with an extra layer of indirection involved: It string-splits and glob-expands names in the string returned by find, so the values are no longer guaranteed to be equivalent to their literals. In short, the filenames it returns can simply be wrong. Commented Jan 20, 2016 at 14:52
  • ...if you want to see this for yourself, create a file with the command touch 'hello * world.png' in a non-empty directory, and see what this code does in result. Commented Jan 20, 2016 at 14:56
  • ...though you have other bugs surrounding your array usage as well, so even if you fixed your find usage you still couldn't correctly handle filenames with spaces from this code. However, those are all quoting issues that shellcheck.net would find for you easily. Commented Jan 20, 2016 at 14:58
  • 1
    You don't need export here, as arrays are not exported anyway. Commented Jan 20, 2016 at 15:29

2 Answers 2

2

Be sure you are using Bash to execute you script. Maybe add a shebang: #! /usr/bin/bash in the first line of your script. You could also check this with a echo $SHELL command in your script. Bash version might also be different. Check with bash --version on the command line.

Sign up to request clarification or add additional context in comments.

2 Comments

But in both ways i defined a #! /usr/bin/sh so why does it work in one of the two programs?
Not just "maybe", and no mystery to it -- any /bin/sh shell promises only POSIX sh compatibility, and POSIX doesn't cover arrays, so there's no guarantee that the feature will be present. OTOH, sh is allowed to be a superset of POSIX sh, so it's also no surprise if it's provided by ksh, bash, or another shell that does allow arrays on some specific machine.
1

The accepted answer is not compliant with best practices -- it'll fail badly with filenames with spaces or newlines in their names. To do it right, if you have a find with -print0:

#!/bin/bash

data=( )
while IFS= read -r -d '' filename; do
  data+=( "$filename" )
done < <(find ~ -iname '*.png' -print0)

By the way, you don't really need arrays for this at all -- or even find:

#!/bin/sh
# This version DOES NOT need bash

# function to run for all PNGs in a single directory
translate_all() {
  for i in "${1:-$HOME}"/*.png; do
    mogrify -crop 1024x794 "$i"
    rm "${i%.png}-1.png"
    mv "${i%.png}-0.png" "$i"   
  done
}

# function to run for all PNGs in a single directory and children thereof
translate_all_recursive() {
  dir=${1:-$HOME}; dir=${d%/}
  translate_all "$dir"
  for d in "$dir"/*/; do
    translate_all_recursive "$d"
  done
done

# actually invoke the latter
translate_all_recursive

References:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.