тройник и конвейеры внутри скрипта bash

мне нужно перенаправить stout и stderr в bash каждый в отдельный файл. хорошо, я выполнил эту команду:

  ((/usr/bin/java -jar /opt/SEOC2/seoc2.jar 2>&1 1>&3 | tee --append /opt/SEOC2/log/err.log) 3>&1 1>&2 | tee --append /opt/SEOC2/log/app.log) >> /opt/SEOC2/log/combined.log 2>&1  &

который отлично работает из командной строки.

попытка поместить ту же самую команду в скрипт bash

 ...
 12 cmd="(($run -jar $cmd 2>&1 1>&3 | tee --append $err) 3>&1 1>&2 | tee --append $log) >> $combined 2>&1"
 ...
 30                 echo -e "Starting servis..." 
 31                 $cmd &
 32                 pid=`ps -eo pid,args | grep seoc2.jar | grep -v grep | cut -c1-6`
 33                 if [ ! -z $pid ]; then
 ...

приводит к такой ошибке:

   root@operator:/opt/SEOC2# seoc2 start
   Starting servis...
   /usr/local/bin/seoc2: line 31: ((/usr/bin/java: dir or file doesn't exist

пытался скрыть эту команду $(), ` ` и т. д., но безрезультатно :(

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

большое спасибо Рене


person user1062331    schedule 18.07.2012    source источник
comment
Не могли бы вы опубликовать, что вы набрали в командной строке bash, чтобы вызвать сбойный скрипт, и показать, откуда вы его вызвали (т. е. какой был текущий каталог, когда вы устали запускать скрипт)   -  person Josh Greifer    schedule 18.07.2012
comment
Вам нужен весь конвейер в одной переменной? Проблема в том, что строка в кавычках заставляет оболочку интерпретировать круглые скобки не как синтаксис оболочки, а как буквальные символы в строке. Проще всего было бы просто написать команду в строке 31. eval $cmd подойдет, но не рекомендуется.   -  person chepner    schedule 18.07.2012
comment
@JoshGreife не то, что вы просите в последней серой рамке из моего исходного сообщения? то есть скрипт находится в /opt/SEOC2, но должен иметь возможность запускаться из любого места. $err, $log, $combined — это абсолютные пути к /opt/SEOC2/log/, в этом примере я запускаю его из /opt/SEOC2.   -  person user1062331    schedule 18.07.2012
comment
хорошо, не был уверен в абсолютных местоположениях. Думал, что это может быть относительный путь.   -  person Josh Greifer    schedule 18.07.2012


Ответы (1)


Если вы храните всю командную строку в переменной, вы должны использовать eval для ее выполнения:

cmd="(($run -jar $cmd 2>&1 1>&3 | tee --append $err) 3>&1 1>&2 | tee --append $log) >> $combined 2>&1"
...
eval $cmd &
person bmk    schedule 18.07.2012
comment
эта подсказка, кажется, работает хорошо, хотя она генерирует дерево ps следующим образом: ‹pre› 15583 pts/0 S 0:00 /bin/bash /usr/local/bin/seoc2 start 15585 pts/0 S 0:00 _ /bin /bash /usr/local/bin/seoc2 start 15586 pts/0 S 0:00 _ /bin/bash /usr/local/bin/seoc2 start 15588 pts/0 Sl 1:41 | _ /usr/bin/java -jar /opt/SEOC2/seoc2.jar ‹/pre› но это не влияет на функциональность, это действительно работает! большое спасибо. р - person user1062331; 18.07.2012
comment
@ user1062331: Эти дополнительные процессы вызваны не eval, а круглыми скобками. Каждый уровень () создаст подоболочку. - person bmk; 18.07.2012