Думаю, да. Но это зависит от того, какую версию Ubuntu (или любого другого дистрибутива) вы пытаетесь использовать.
Последняя версия может быть немного тяжелой, поэтому, если это не сработает, вы можете попробовать более старую версию. У вас должна быть возможность проверить требования на веб-сайте дистрибутива.
Кроме того, в какой-то момент будет работать только одна ОС, поэтому, если вы вообще думаете, что запуск двух ОС потребует двойной памяти, то это не так.
4 ГБ, i5 должно хватить, если не попробовать старые версии.
Для этого вам не нужно запускать другую оболочку. Чтобы обработать все файлы, соответствующие выражению glob, просто используйте glob в командной строке программы, которую вы хотите запустить в конце:
convert *.png -whatever /some/output/path
Если вам нужен доступ только к части файлов, сохраните их в массиве и разрежьте или проиндексируйте:
files=(*.png)
convert "${files[0]}" "${files[@]:1}" -evaluate-sequence "$var1"../out2/"${files[0]}"
("${files[0]}"
— имя первого файла, "${files[@]:1}"
заменяется на все остальные)
Оттуда мы можем обрабатывать файлы по сотне за раз:
for (( i=0; i < "${#files[@]}" ; i+=100 )); do
convert "${files[@]:i:100}" -evaluate-sequence "$var1"../out2/"${files[i]}"
done
То есть, если я правильно интерпретировал вашу xargs
команду. Похоже, что первое имя файла передается в качестве нулевого аргумента вsh -c
(обычно как имя оболочки ).
Но чтобы ответить на вопрос так, как вы его задали, вы можете export
указать переменную, чтобы сделать ее видимой для внутренней оболочки, или поместить ее в двойные кавычки, чтобы она расширялась внешней оболочкой. Например.
var=foo
export var
echo bar | xargs sh -c 'echo "$var" "$1"' sh
или
var=foo
echo bar | xargs sh -c "echo '$var' "'"$1"' sh
Оба выхода foo bar
. Проход через среду лучше, поскольку синтаксис чище (обратите внимание на различные типы кавычек вокруг $var
и $1
в последнем ), и любые кавычки в значении переменной не вызовут проблем, так как они будет во втором случае.
Нет, вам не нужно передавать список имен файлов.
var1=$1
find. -maxdepth 1 -type f -name '*.png' -exec sh -c '
var1=$1; first=$2; shift 2
convert "$first" "$@" -evaluate-sequence "$var1"../out2/"$first"' sh "$var1" {} +
То есть дайте внутреннюю дочернюю оболочку $var1
в качестве первого аргумента (нулевой аргумент должен быть именем оболочки ).
Внутренняя оболочка удаляет $var1
из списка параметров, а также делает то же самое для первого имени пути, которое find
находит (Я не знаю почему, но это, по крайней мере, делает его эквивалентным тому, что я поверьте, ваш код делает ), а затем смещает их с $@
с помощью shift 2
.
Если вам нужно сделать это партиями ровно по 100:
var1=$1
find. -maxdepth 1 -type f -name '*.png' -print0 |
xargs -0 -n 100 sh -c '
var1=$1; first=$2; shift 2
convert "$first" "$@" -evaluate-sequence "$var1"../out2/"$first"' sh "$var1"
Причина, по которой это безопаснее, чем конвейерная передача вывода ls
, заключается в том, что пути передаются как список с нулевым -завершением, а не как список с символом новой строки -. Сценарий sh
одинаков в обоих вариантах и принимает $var1
в качестве аргумента командной строки.
Причина, по которой ваш код не работает, заключается в том, что оболочка sh -c
не знает $var1
своей родительской оболочки.
Связанные:
sh -c
— это новая оболочка, поэтому вам нужно выполнить export
из $var1
, чтобы дочерние процессы имели ее или передавали в sh -c
в качестве аргумента.
Другая проблема с вашим примером заключается в том, что у вас есть переменная внутри одиночных тиков.