2014-09-24 5 views
0

My Aim -> Файлы Список из команды должен читаться по строкам и использоваться как часть другой команды.Чтение пути к файлам в виде строки в сценарии оболочки

Описание -> Команда в Linux возвращает

archive/Crow.java 
archive/Kaka.java 
mypmdhook.sh 

, который хранится в changed_files переменной. Я использую следующее время цикла, чтобы прочитать строку файлов по линии и использовать его как часть команды PMD

while read each_file 
do 
     echo "Inside Loop -- $each_file" 
done<$changed_files 

Я новичок в написании сценария оболочки, но мое предположение было то, что линии будут уже разделены в цикл и распечатаны на каждой итерации, но вместо этого я получаю следующее сообщение об ошибке -

mypmdhook.sh: 7: mypmdhook.sh: cannot open archive/Crow.java 
archive/Kaka.java 
mypmdhook.sh: No such file 

можете ли вы сказать мне, как я могу просто получить значение в виде строки, а не в виде файла, что открыт. Кстати, файл существует, что заставило меня чувствовать себя еще более запутанным (и позже использовать его внутри команды). Я был бы доволен любым ответом, который поможет мне понять и решить эту проблему.

+0

Возможный дубликат [Bash - Как подключить вход к циклу while и перенести переменные после окончания цикла) (http://stackoverflow.com/questions/19570413/bash-how-to-pipe-input-to-while- петля-и-perserve-переменные-после-петли-концов) – MrTux

ответ

0

Что здесь происходит, что значение вашей переменной $changed_files подставляется в вашу команду, и вы получите что-то вроде

while read each_file 
do 
     echo "Inside Loop -- $each_file" 
done < archive/Crow.java 
archive/Kaka.java 
mypmdhook.sh 

то оболочка пытается открыть файл для перенаправления ввода и, очевидно, не удается.

Дело в том, что переназначения (например <, >, >>) в большинстве случаев принимают имена файлов, но то, что вам действительно нужно, чтобы дать содержимое переменной в стандартный ввод.Самый очевидный способ сделать это

echo $changed_files | while read each_file; do echo "Inside Loop -- $each_file"; done 

Вы можете также использовать for петлю вместо while read:

for each_file in $changed_files; do echo "inside Loop -- $each_file"; done 

Я предпочитаю использовать while read ..., если есть вероятность, что некоторые имя файла может содержать пробелы, но в большинстве случаев for ... in будет работать на вас.

0

Вместо того, чтобы хранить выходное данные команды в переменном использовании while цикла вроде этого:

mycommand | while read -r each_file; do echo "Inside Loop -- $each_file"; done 

Если вы используете BASH вы можете использовать process substitution:

while read -r each_file; do echo "Inside Loop -- $each_file"; done < <(mycommand) 

кстати вашу попытку done<$changed_files будет предполагать что changed_files представляет файл.

1

Поскольку у вас есть данные, хранящиеся в переменной, используйте «here string» вместо файла Перенаправление:

changed_files="archive/Crow.java 
archive/Kaka.java 
mypmdhook.sh" 
while read each_file 
do 
     echo "Inside Loop -- $each_file" 
done <<< "$changed_files" 
Inside Loop -- archive/Crow.java 
Inside Loop -- archive/Kaka.java 
Inside Loop -- mypmdhook.sh 

Чрезвычайно важно процитировать "$changed_files" для того, чтобы сохранить переводы строк, так что в то время как Простой цикл работает так, как вы ожидаете. Эмпирическое правило: всегда укажите переменные, если вы точно не знаете, почему вы хотите оставить кавычки.

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

  • Нет связанных вопросов^_^