Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Общий по Linux (http://forum.oszone.net/forumdisplay.php?f=9)
-   -   bash: Как выполнить многострочный результат другой команды (http://forum.oszone.net/showthread.php?t=54138)

shivtorov 22-09-2005 07:14 357407

bash: Как выполнить многострочный результат другой команды
 
Некий набор grep-ов, sed-ов и awk-ов генерит последовательность строк команд. Их необходимо выполнить. Как это сделать?

Тривиальный пример:
Код:

echo ls ; echo who
дает результат
Код:

ls
who

Пытаемся выполнить следующим образом
Код:

`echo ls ; echo who`
получаем сообщение об ошибке:
Код:

ls: who: No such file or directory
Это происходит потому, что все строки у меня "склеиваются" в одну команду.
Если команды в `` наколбасят ровно одну строку/команду, то все рабоает.

Как их разделить на две команды?

xamelion 22-09-2005 09:20 357429

Незнаю как другие, я неуловил в вопросе что нужно зделать

mar 22-09-2005 09:43 357435

shivtorov
действительно ничего не понятно :(
если просто хотите выполнить две команды подряд, то выполняйте на здоровье
Код:

ls; who;
если хотите передавать результат одной команды другой, импользуйте |
если что-то другое - напишите, но попонятней, pls

fossil 23-09-2005 09:59 357853

Код:

'echo ls' ; 'echo who'

Yura 24-09-2005 18:34 358332

В данном случае должно работать: 'echo ls;' ; 'echo who;'.
А вообще хотелось бы на сам скрипт посмотреть.

shivtorov 02-10-2005 06:51 360772

Ситуация такая:
Поставил RedHat Enterprise Linux 3 в минимальной конфигурации.
Потом решил доустановить X. Пришлось в одной консоли в vi открыть файлик comps.xml, в котором описаны все пакеты дистрибутива, а в другой консоли для каждого нужного мне пакеты рачками исполнять rpm -i ...
Быстро понял, что это очень геморно и решил научиться-таки пользоваться базовами иниксовыми инструментами. Вот и сваял такую командочку:
Код:

cat ../base/comps.xml | sed '0,/base-x/d' | sed '0,/packagelist/d' | sed '/packagelist/,$d' | grep mandatory | sed s/.*\"\>/"find . -name \""/ | sed s/\<.*/"-\[0-9]*\" -exec rpm -ivh --aid {} \\\;"/
Эта штука выдает на консоль результат:
Код:

  find . -name "bitmap-fonts-[0-9]*" -exec rpm -ivh --aid {} \;
  find . -name "desktop-backgrounds-basic-[0-9]*" -exec rpm -ivh --aid {} \;
  find . -name "switchdesk-[0-9]*" -exec rpm -ivh --aid {} \;
                              ....... output trancated ........

А когда я свою командочку обрамляю ``, то эта сволочь не работает ((
Пробывал по совету Yura :
Код:

cat ../base/comps.xml | sed '0,/base-x/d' | sed '0,/packagelist/d' | sed '/packagelist/,$d' | grep mandatory | sed s/.*\"\>/"\`find . -name \""/ | sed s/\<.*/"-\[0-9]*\" -exec rpm -ivh --aid {} \\\;\` ;"/
теперь эта штука выдает:
Код:

  `find . -name "bitmap-fonts-[0-9]*" -exec rpm -ivh --aid {} \;` ;
    `find . -name "desktop-backgrounds-basic-[0-9]*" -exec rpm -ivh --aid {} \;` ;
  `find . -name "switchdesk-[0-9]*" -exec rpm -ivh --aid {} \;` ;
                              ....... output trancated ........

Но она все равно не запускается с помощью ``. Только теперь ругается по другому. Если в первоначальном варианте проблема была в том, что все строки воспринимались системой как аргументы первого find, то теперь на исполнения идут не команды find, промежуточный результат получившийся после предпоследненго sed-а.

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

Помогите запустить мои find-ы!!!

bdancer 02-10-2005 12:59 360820

>Потом решил доустановить X.

И ради этого надо так извращаться???????

BeerMan 02-10-2005 19:42 360868

...а не проще почитать доки по yum??? в Красной Шляпе оно вроде есть...

shivtorov 03-10-2005 08:47 360962

to BeerMan
to bdancer
Как решить задачу обходным маневром я знаю (описывал его в своем посте). Меня интересует как решить задачу в лоб - в основном в учебных целях. Это ведь базовые инструменты и ими необходимо уметь пользоваться.

to Модераторы
Перебросьте, пожалуйста, эту тему в раздел программирование. Наверное, эта тема ближе к тому разделу.

gf100 03-10-2005 14:39 361065

А попробовать добавить за строкой | sh или | bash

bdancer 03-10-2005 18:37 361135

Кривовато конечно (вместо двух sed'ов одного бы хватило, но... :))), тока path на пути замени.
Код:

for package in `cat /path/comps.xml | sed '0,/base-x/d' | sed '0,/packagelist/d' | sed '/packagelist/,$d' | grep mandatory | sed 's/.*\">//' | sed 's/<\/.*//'`;
do
        echo "Searching and installing package: $package..."
        find <path> -name "$package-[0-9]*" -exec rpm -ivh --aid {} \;
done


shivtorov 03-10-2005 19:18 361141

Respect
 
Respect qt100 and bdancer

qt100 попал в точку - как раз то, что я и хотел получить. Respect!
Вариант bdancer-а чуть глубже в программинг, но радует дополнительным фунционалом. Respect!

Мой итоговый рабочий вариант (с учетом пожеланий bdancer-а)
Код:

cat ../base/comps.xml |
sed -e '0,/base-x/d' -e '0,/packagelist/d' -e '/packagelist/,$d'|
grep manda |
sed -e 's/.*\"\>/"find . -name \""/' -e 's/\<.*/"-\[0-9]*\" -exec rpm -ivh --aid {} \\\; ;"/' |
bash

Кстати, есть какие-нибудь достоверные сведения о различии в быстродействии двух вариантов:
1) sed <параметры> | sed <параметры> | sed <параметры>
2) sed -e <параметры> -e <параметры> -e <параметры>

bdancer 04-10-2005 10:20 361288

shivtorov
Я немного не то имел в виду, просто описал неправильно.
Я про свой вариант и два последних sed'a (sed 's/.*\">//' | sed 's/<\/.*//'`;) которые вырезают название пакета, там точно одним regex'пом можно обойтись.

>о различии в быстродействии двух вариантов
2-ой имхо быстрее ибо пайпов нет, хотя черт его знает.

И мой вариант, имхо, быстрее ибо не плодит лишних процессов в виде запускания шелла для интерпретации команды.


Время: 10:19.

Время: 10:19.
© OSzone.net 2001-