0

I am currently working on a bash script where I must download files from our mySQL database, host them somewhere different, then update the database with the new location for the image. The last portion is my problem area, creating the array full of filenames and iterating through them, replacing the file names in the database as we go.

For whatever reason I keep getting these kinds of errors:

not found/X2b6qZP.png: 1: /xxx/images/X2b6qZP.png: ?PNG /xxx/images/X2b6qZP.png: 2: /xxx/images/X2b6qZP.png: : not found /xxx/images/X2b6qZP.png: 1: /xxx/images/X2b6qZP.png: Syntax error: word unexpected (expecting ")")

files=$($DOWNLOADDIRECTORY/*)
files=$(${files[@]##*/})

# Iterate through the file names in the download directory, and assign the new values to the detail table.

for file in "${files[@]}"
    do
        mysql -h ${HOST} -u ${USER} -p${PASSWORD} ${DBNAME}  "UPDATE crm_category_detail SET detail_value = 'http://xxx.xxx.x.xxx/img/$file' WHERE detail_value LIKE '%imgur.com/$file'"
    done
Matt Clark
  • 27,671
  • 19
  • 68
  • 123
Downwithopp
  • 73
  • 1
  • 8

4 Answers4

3

You are trying to execute a glob as a command. The syntax to use arrays is array=(tokens):

files=("$DOWNLOADDIRECTORY"/*)
files=("${files[@]##*/}")

You are also trying to run your script with sh instead of bash.

Do not run sh file or use #!/bin/sh. Arrays are not supported in sh.

Instead use bash file or #!/bin/bash.

that other guy
  • 116,971
  • 11
  • 170
  • 194
2

whats going on right here?

files=$($DOWNLOADDIRECTORY/*)

I dont think this is doing what you think it is doing.

According to this answer, you want to omit the first $ to get an array of files.

files=($DOWNLOADDIRECTORY/*)

I just wrote a sample script

#!/bin/sh
alist=(/*)
printf '%s\n' "${alist[@]}"

Output

/bin
/boot
/data
/dev
/dist
/etc
/home
/lib
....
Community
  • 1
  • 1
Matt Clark
  • 27,671
  • 19
  • 68
  • 123
  • I am trying to create an array of file names, from within that directory. – Downwithopp Dec 18 '15 at 00:21
  • And this does exactly that, try it. – Matt Clark Dec 18 '15 at 00:24
  • Awesome, thanks a ton. Now if I iterate through the array, and plug in $files in my mySQL text, will it use the filenames? – Downwithopp Dec 18 '15 at 00:30
  • 1
    try it out. my suggestion would be assigning the sql text to a variable, and then using the variable in the mysql command. That way you can easily echo the query string to find possible problems. Cheers, and happy coding. – Matt Clark Dec 18 '15 at 00:31
2

Your assignments are not creating arrays. You need arrayname=( values for array ) as the notation. Hence:

files=( "$DOWNLOADDIRECTORY"/* )
files=( "${files[@]##*/}" )

The first line will give you all the names in the directory specified by $DOWNLOADDIRECTORY. The second carefully removes the directory prefix. I've used spaces after ( and before ) for clarity; the shell neither requires nor objects to them. I used double quotes around the variable name and expansions to keep things sane when name do contain spaces etc.

Although it isn't immediately obvious why you might do this, its advantage over many alternatives is that it preserves spaces etc in file names.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

You could just loop directly over the files:

for file in "$DOWNLOADDIRECTORY"/*; do
    file="${file##*/}" # or file=$(basename "$file")
    # MySQL stuff
done

Some quoting added in case of spaces in paths.

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116