Я не уверен, что точно понимаю, что вы хотите сделать.Это чтобы выполнить что-то вроде этих команд, но параллельно?
sh script.sh $arg1 $arg2 $arg3 file_list1.dat
sh script.sh $arg1 $arg2 $arg3 file_list2.dat
sh script.sh $arg1 $arg2 $arg3 file_list3.dat
...etc
Если это правильно, это должно работать:
Ncores=4
printf '%s\0' file_list*.dat | xargs -0 -P "$Ncores" -n 1 sh script.sh "$arg1" "$arg2" "$arg3"
Две основные проблемы в вашей версии заключались в том, что вы былипередача «Ncores» в виде литеральной строки (вместо использования $Ncores
для получения значения переменной), и что у вас было [ ]
вокруг команды и аргументов (что просто не является частью синтаксиса оболочки).Я также добавил двойные кавычки вокруг всех ссылок на переменные (обычно это хорошая практика) и использовал printf '%s\0'
(и xargs -0
) вместо ls
.
Почему я использовал printf
вместо ls
?Потому что ls
здесь не делает ничего полезного, что printf
или echo
или что-то еще не могло бы быть так же хорошо.Вы можете думать о ls
как о средстве получения списков имен файлов, но в этом случае подстановочное выражение file_list*.dat
расширяется до списка файлов до , когда команда запускается;все, что ls
будет делать с ними, это посмотреть на каждого, сказать «да, это файл» самому себе, а затем распечатать его.echo
может сделать то же самое с меньшими накладными расходами.Но с ls
или echo
вывод может быть неоднозначным, если любое имя файла содержит пробелы, кавычки или другие забавные символы.Некоторые версии ls
пытаются «исправить» это, добавляя кавычки или что-то вокруг имен файлов с забавными символами, но это может совпадать или не совпадать с тем, как xargs
анализирует ввод (если это вообще происходит).
Но printf '%s\0'
является однозначным и предсказуемым - он печатает каждую строку (в данном случае имя файла) с последующим символом NULL, и это именно то, что xargs -0
принимает в качестве входных данных, поэтому нет никакой путаницыили неправильный анализ.
Ну, хорошо, есть один крайний случай: если нет подходящих файлов, шаблон с подстановочными знаками будет просто пропущен буквально, и он попытается запустить скрипт снерасширенная строка "file_list * .dat" в качестве аргумента.Если вы хотите избежать этого, используйте shopt -s nullglob
перед этой командой (и shopt -u nullglob
после, чтобы вернуться в нормальный режим).
О, и еще одна вещь: sh script.sh
не самая лучшаяспособ запуска скриптов.Дайте сценарию правильную строку shebang в начале (#!/bin/sh
, если он использует только базовые функции оболочки, #!/bin/bash
или #!/usr/bin/env bash
, если он использует bashisms ), и запустите его с ./script.sh
.