2016-01-20 2 views
0

Привет У меня есть следующие проблемы: Этот код подножка в раковине-скрипт без ошибок синтаксиса на моем компьютере, но на другом сервере, я получаю ошибку синтаксиса «(» неожиданныйСоздание массива в оболочке с командой поиска

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 
+1

Не то, что это не безопасно для дорожек/файлов с пробелами в них. Также цитируемый '' 'не распространяется правильно, так что это * не может * работать вообще, как написано здесь. И вам не нужно (или нужно) «экспортировать» здесь. –

+1

Это в основном http://mywiki.wooledge.org/DontReadLinesWithFor с дополнительным уровнем косвенности: он разделяет строки и glob-расширяет имена в строке, возвращаемой 'find', поэтому значения больше не гарантируются что эквивалентно их литералам. Короче говоря, имена файлов, которые он возвращает, могут быть ошибочными. –

+0

... если вы хотите это сделать сами, создайте файл с командой 'touch 'hello * world.png'' в непустой директории и посмотрите, что делает этот код в результате. –

ответ

2

Убедитесь, что вы используете Bash для выполнения сценария. Возможно, в первой строке вашего скрипта добавьте shebang: #! /usr/bin/bash. Вы также можете проверить это с помощью команды echo $SHELL в вашем скрипте. Версия Bash также может быть различной. bash --version в командной строке.

+0

Но в обоих случаях я определил #!/usr/bin/sh, так почему он работает в одной из двух программ? –

+0

он работает с bash ... mysterious .. спасибо –

+0

Не просто «может быть», и никакой тайны к нему - любая оболочка '/ bin/sh' обещает только совместимость POSIX sh, а POSIX не охватывает массивы, поэтому нет никакой гарантии, что функция будет присутствовать. OTOH, 'sh' * * разрешено * быть надмножеством POSIX sh, так что также неудивительно, если он предоставлен ksh, bash или другой оболочкой, которая * позволяет * разрешать массивы на определенной машине. –

1

Принятый ответ не соответствует передовым методам - он плохо с ошибками с именами файлов с пробелами или символами новой строки в их именах. Для того, чтобы сделать это правильно, если у вас есть find с -print0:

#!/bin/bash 

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

Кстати, вы не действительно нужны массивы для этого на всех - или даже 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 

Ссылки:

  • BashFAQ #001 («Как я могу прочитать файл (поток данных, переменную) по очереди (и/или поле за полем)?», Показывая правильную практику; искать -print0).
  • UsingFind (аналогичным образом).
  • BashPitfalls #1
  • Don't Read Lines With For (из вики Wooledge)
Смежные вопросы