Вы часто злоупотребляете кошачьими - вам нужно просто перенаправить, а не пайп к cat
, который добавляется.
Вы можете избежать промежуточного файла $i.sh
, связав весь вывод, который идет в файлс одним перенаправлением ввода / вывода, которое направляет канал непосредственно в оболочку - нет необходимости в очистке промежуточного файла (вы не показали, что это происходит) или операции chmod
.
Я бы сделал этоиспользуя фигурные скобки:
{
echo "..."
ls
echo "..."
} | sh
Однако, когда я посмотрел на сценарий в этой форме, я понял, что в этом нет необходимости.Я оставил начальную часть вашего сценария без изменений, но цикл намного проще, как этот:
#/bin/sh
read -d '' commands <<EOF
#list of directories goes here
dir1
dir2
dir3
etc...
EOF
for i in $commands
do
(
cd $SPECIALPATH/$i
ls |
while read q
do uuencode $q $q | sendmail $i
done
)
done
Я предполагаю, что команда sendmail
работает - это не так, как япопробуйте отправить письмо.Я бы, вероятно, использовал mailx
или что-то подобное, и я бы тоже не стал использовать uuencode
(я бы использовал кодировку base-64, оставленную для моих собственных устройств):
do uuencode $q $q | mailx -s "File $q" $i@tumblr.com
Скрипт также использует круглые скобки вокруг команды cd
.Это означает, что команда cd
и последующие выполняются в под-оболочке, поэтому родительский скрипт не меняет каталог.В этом случае с абсолютным путем к $ SPECIALDIR это не будет иметь большого значения.Но, как правило, это часто облегчает жизнь, если вы изолируете такие изменения в каталогах.
Я бы, вероятно, еще больше упростил его для общего повторного использования (хотя мне нужно было бы добавить что-то, чтобы убедиться, что SPECIALPATHустановить соответствующим образом):
#/bin/sh
for i in "$@"
do
(
cd $SPECIALPATH/$i
ls |
while read q
do uuencode $q $q | sendmail $i
done
)
done
Затем я могу вызвать его с помощью:
script-name $(<list-of-dirs)
Это означает, что без редактирования сценария его можно повторно использовать для любого списка каталогов.
Промежуточный шаг 1:
for i in $commands
do
(
cd $SPECIALPATH/$i
{
echo "read -d '' directives <<EOF"
ls
echo "EOF"
echo "for q in $directives"
echo "do"
echo " uuencode $q $q | sendmail $i"
echo "done"
} |
sh
)
done
Лично мне легче читать сгенерированный скрипт, если генерирующий код делает сгенерированный скрипт понятным - используя несколько команд echo.Это включает в себя отступ кода.
Промежуточный шаг 2:
for i in $commands
do
(
cd $SPECIALPATH/$i
{
ls |
echo "while read q"
echo "do"
echo " uuencode $q $q | sendmail $i"
echo "done"
} |
sh
)
done
Мне не нужно считывать данные в переменную, чтобы пройти по каждому элементу списка один раз - просточитать каждую строку по очереди.Механизм while read
часто также полезен для разбиения строки на несколько переменных: while read var1 var2 var3 junk
будет читать первое поле в $var1
, второе в $var2
, третье в $var3
, и если что-то осталосьболее, это входит в $junk
.Если вы сгенерировали данные точно, мусора не будет;но иногда приходится иметь дело с данными других людей.