Переменная область применения в трубах?

Думаю, да. Но это зависит от того, какую версию Ubuntu (или любого другого дистрибутива) вы пытаетесь использовать.

Последняя версия может быть немного тяжелой, поэтому, если это не сработает, вы можете попробовать более старую версию. У вас должна быть возможность проверить требования на веб-сайте дистрибутива.

Кроме того, в какой-то момент будет работать только одна ОС, поэтому, если вы вообще думаете, что запуск двух ОС потребует двойной памяти, то это не так.

4 ГБ, i5 должно хватить, если не попробовать старые версии.

1
14.07.2018, 21:43
3 ответа

Для этого вам не нужно запускать другую оболочку. Чтобы обработать все файлы, соответствующие выражению 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в последнем ), и любые кавычки в значении переменной не вызовут проблем, так как они будет во втором случае.

0
27.01.2020, 23:43

Нет, вам не нужно передавать список имен файлов.

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своей родительской оболочки.

Связанные:

1
27.01.2020, 23:43

sh -c— это новая оболочка, поэтому вам нужно выполнить exportиз $var1, чтобы дочерние процессы имели ее или передавали в sh -cв качестве аргумента.

Другая проблема с вашим примером заключается в том, что у вас есть переменная внутри одиночных тиков.

0
27.01.2020, 23:43

Теги

Похожие вопросы