2012-04-29 2 views
4

Я пытаюсь сделать скрипт для добавления всех файлов, заканчивающихся .hash, для проверки md5deep. Файлы с пространством в их имени, похоже, нарушают этот скрипт.Экранирование пространства в скрипте bash

#!/bin/bash 
XVAR="" 
for f in *.hash 
do 
    XVAR="$XVAR -x $f " 
done 
md5deep -e $XVAR -r * 

Всякий раз, когда я запустить сценарий с файлом под названием "O S.hash" я хотел бы получить

O: No such file or directory 

Если я изменить XVAR="$XVAR -x $f " к XVAR="$XVAR -x \'$f\' " или XVAR="$XVAR -x \"$f\" "

md5deep будет пронизывают вход как "O вместо

"O: No such file or directory 

эхо-сигнал переменной в сценарии показывает XVAR как -x 'O S.hash' или -x "O S.hash"

ручной ввод команды в оболочке, таких как md5deep -e -x "O S.hash" -r * работает, но если его в сценарии команда, кажется, сломать

ответ

3

Это не приятное решение, но, кажется, он будет работать:

find . -name '*.hash' -printf "-x\0%p\0" | xargs -0 md5deep -r * -e 

Это на самом деле не делает точно так же, как ОП хотел, так вот модификация, как предложил Тим Потье и Джонатан Леффлера:

find . -maxdepth 1 -name '*.hash' -printf "-x\0%p\0" | xargs -0 md5deep -r * -e 
+0

Если есть подкаталоги, содержащие файлы .hash, это приведет к посторонним файлам, указанным в командной строке. –

+0

Да, просто добавьте '-maxdepth 1'. –

+0

работает отлично :) – anselm

2

Теперь вы знаете, почему люди в системах Unix традиционно избегали имен файлов с пробелами в них (и именами каталогов аналогично) —. Это неприятность (чтобы быть вежливой об этом), чтобы запрограммировать оболочку для обработки таких имен. Оболочка была разработана для использования в системах без таких имен. Новые строки также вызывают много горя.

С bash вашим лучшим решением является использование массива для хранения элементов, а затем "${array[@]}", чтобы их перечислить; это почти тривиальное:

declare -a XVAR 

for file in *.hash 
do 
    XVAR+=("-x" "$file") 
done 

md5deep -e "${XVAR[@]}" -r * 

(Эксплуатируя расширение массива обозначения упоминаемого Gordon Davisson См раздел §6.7 «Массивы» о bash справочного руководства (для Bash 4.1) для большого количества информации массива, смотрите раздел. §3.4 «Параметры оболочки» для оператора +=.)

Если вы по какой-то причине не можете использовать массивы, вам понадобится программа, которая ускользает от своих аргументов, чтобы оболочка не искажала вещи. Я такая программа, называется escape:

XVAR= 
for file in *.hash 
do 
    name=$(escape "$file") 
    XVAR="$XVAR -x $file" 
done 
eval md5deep -e $XVAR -r * 

С Eval, это сложно использовать; он работает, но использует массивы.

+1

Вот более простой способ добавления записей в массив: 'XVAR + = (- x" $ file ")' –

+0

Ah; спасибо, @GordonDavisson; Я знал, что должен что-то игнорировать, но я не был уверен, что! В разделе «Массивы» (§6.7) в справочном руководстве Bash (4.1) не упоминается '+ ='; когда вы знаете, что вам нужно искать '+ =', вы можете найти обозначение, упомянутое в п. 3.4, и там также упоминается поведение для массивов. –

Смежные вопросы