alias rm.dup 'perl -ne '\''print unless $dup{$_}++'\'' \!* &'
Поскольку нельзя вставить одинарную кавычку в одинарные кавычки, один из способов — вырваться из одинарной кавычки, вставить буквальную кавычку, а затем перезапустить кавычки.
'perl -ne '\''print unless $dup{$_}++'\'' \!* &'
|---------|B |-----------------------|D |------|
A C E
Другой способ:
alias rm.dup 'perl -ne "print unless "\$"dup{"\$"_}++" \!* &'
Оболочка анализирует конвейеры (и перенаправляет, и заключает в кавычки, и экранирует и... )перед раскрытием переменных, поэтому, если вы поместите конвейер (или перенаправление или... )в переменную, когда он расширен, уже слишком поздно для нормального функционирования; в этот момент это просто обычный аргумент команды. См. BashFAQ #50 :Я пытаюсь поместить команду в переменную, но сложные случаи всегда терпят неудачу!
Решение :В этом случае я бы рекомендовал использовать eval
. eval
имеет очень плохую репутацию магнита для насекомых, потому что его легко использовать не по назначению опасным образом. По сути, его цель состоит в том, чтобы выполнять данные, как если бы они были синтаксисом и командами оболочки, и это означает, что грань между исполняемым кодом и инертными данными (, такими как имена файлов ), даже слабее, чем обычно. Но в этом случае данные, считанные из ZLD _Command _list.txt, должны обрабатываться как синтаксис и команды оболочки. Если в файле есть rm -R /
, предполагается, что удалит всю файловую систему.
Тем не менее, вы все равно должны соблюдать правила цитирования. Это означает двойное -цитирование переменных, например eval "$variable1"
вместо простого eval $variable1
. Кроме того, я рекомендую использовать $()
вместо обратных кавычек (, см. BashFAQ #82 ), но поскольку вы просто собираетесь echo
получить результат, почему бы просто не выполнить команду напрямую?
Другие возможные оптимизации :Вместо того, чтобы копировать значение $Command
в $variable1
, просто используйте его напрямую. Вместо перенаправления вывода каждой команды по отдельности, почему бы не перенаправить вывод всего цикла?
Вот моя версия, со всем вышеперечисленным исправленным:
#!/bin/bash
while IFS=#, read -r Command_info1 Command; do
echo "$Command_info1"
eval "$Command"
done < /ZLD_Implement/ZLD_Command_list.txt > /ZLD_Implement/ZLD_Implement.txt
О, и вы хотите записывать вывод ошибок, а также стандартный вывод команд? Если это так, добавьте 2>&1
после окончательного перенаправления.