Как я могу использовать канал или перенаправить в команде qsub?
Есть некоторые команды, которые я хотел бы запустить в сетке с использованием qsub (SGE 8.1.3, CentOS 5.9), для которых требуется использовать канал (|
) или перенаправление (>
). Например, допустим, я должен распараллелить команду
echo 'hello world' > hello.txt
(Очевидно, упрощенный пример: в действительности мне может понадобиться перенаправить вывод программы типа bowtie непосредственно в samtools). Если бы я сделал:
qsub echo 'hello world' > hello.txt
результирующее содержание hello.txt
будет выглядеть
Your job 123454321 ("echo") has been submitted
Точно так же, если бы я использовал трубу (echo "hello world" | myprogram
), это сообщение - все, что будет передано myprogram
, а не фактический стандартный вывод.
Я знаю, что мог бы написать небольшой скрипт bash, каждый из которых содержал бы команду с pipe / redirect, а затем сделать qsub ./myscript.sh
, Тем не менее, я пытаюсь запустить много параллельных заданий одновременно, используя сценарий, поэтому мне придется написать много таких сценариев bash, каждый из которых имеет несколько отличную команду. При написании сценариев это решение может начать казаться очень хакерским. Пример такого скрипта в Python:
for i, (infile1, infile2, outfile) in enumerate(files):
command = ("bowtie -S %s %s | " +
"samtools view -bS - > %s\n") % (infile1, infile2, outfile)
script = "job" + str(counter) + ".sh"
open(script, "w").write(command)
os.system("chmod 755 %s" % script)
os.system("qsub -cwd ./%s" % script)
Это расстраивает по нескольким причинам, среди которых, что моя программа не может даже удалить многие jobXX.sh
впоследствии сценарии для очистки после себя, так как я не знаю, как долго работа будет ждать в очереди, и сценарий должен быть там, когда работа начинается.
Есть ли способ предоставить мой полный echo 'hello world' > hello.txt
команда для qsub без необходимости создания другого файла, содержащего команду?
3 ответа
Вы можете сделать это, превратив его в bash -c
команда, которая позволяет поставить |
в цитируемом заявлении:
qsub bash -c "cmd <options> | cmd2 <options>"
Как отметил @spuder в комментариях, кажется, что в других версиях qsub (не SGE 8.1.3, который я использую) можно решить проблему с помощью:
echo "cmd <options> | cmd2 <options>" | qsub
также.
Хотя мой ответ немного запаздывает, я добавляю его для любых входящих зрителей. Чтобы использовать pipe / direct и представить это как работу qsub, вам нужно сделать пару вещей. Но сначала использование qsub в конце канала, как вы делаете, приведет к тому, что в очередь будет отправлено только одно задание (т. Е. Ваш код будет выполняться последовательно, а не распараллеливаться).
- Запустите qsub с включенным двоичным режимом, поскольку поведение qsub по умолчанию скорее ожидает скомпилированный код. Для этого вы используете флаг "-b y" для qsub, и вы избежите ошибок типа "команда, необходимая для двоичного режима" или "длина скрипта не соответствует объявленной длине".
- эхо каждый вызов qsub и затем передать это в оболочку.
Предположим, у вас есть файл params-query.txt, который содержит несколько команд bowtie и конвейерные вызовы samtools следующей формы:
bowtie -q query -1 param1 -2 param2 ... | samtools ...
Чтобы отправить каждый запрос как отдельное задание, сначала подготовьте модули командной строки от STDIN до xargs STDIN. Обратите внимание, что кавычки вокруг фигурных скобок важны, если вы отправляете команду по конвейеру. Таким образом, весь ваш запрос обрабатывается как единое целое.
cat params-query.txt | xargs -i echo qsub -b y -o output_log -e error_log -N job_name \"{}\" | sh
Если это не сработало так, как ожидалось, тогда вам, вероятно, лучше сгенерировать промежуточный вывод между bowtie и samtools, прежде чем вызывать samtools, чтобы принять этот промежуточный вывод. Вам не нужно изменять вызов qsub через xargs, но код в params-query.txt должен выглядеть так:
bowtie -q query -o intermediate_query_out -1 param1 -2 param2 && samtools read_from_intermediate_query_out
На этой странице есть интересные трюки с qsub, которые могут вам понравиться
grep http *.job | awk -F: '{print $1}' | sort -u | xargs -I {} qsub {}