Кажется, что то, что вы делаете, определенно будет очень медленным, поскольку каждый раз, когда вы var = $ (command substitute)
, вы должны останавливаться и ждать его вывода, прежде чем переходить к следующему шагу. Готов поспорить, что вы бы подождали гораздо меньше, если бы просто обработали его в потоке с помощью sed,
редактора потока :
NODE="$(pargs -l $PID | sed -rn '/(-DnodeId)=(\S*)/{s//\2/pq}')"
Я не совсем уверен насчет одинарных кавычек - Я только что набрал это на своем телефоне, но функция sed y
определенно справится с этим, если она вам все еще нужна.
Выше Джош демонстрирует неудачный случай. Вероятно, было бы намного проще просто добавить:
${NODE:?PID not found...quitting}
После выполнения вышеуказанной команды sed
.
Мне приходит в голову, что они не обязательно уже разделены строкой, мы можем справиться с этим достаточно легко с помощью еще 1 | pipe
- все еще в одном потоке данных, а также с учетом возможности нескольких совпадений :
. <<PIDSED /dev/stdin
$(pargs -l $PID |\
sed -rn 's/(-DnodeId)=(\S*)/\
echo "NODE$((i=i+1))=\2" ;/gp' |\
. /dev/stdin)
PIDSED
Если вы вместо
>> /tmp/user_count.txt
будет записывать новый файл для каждого сервера:
do
(
printf '%s\n%s\n' '**********' "$i"
ssh sandeepj@${i} "awk -F\: '{print \$1}' /etc/passwd"
) > "/tmp/user_count_${i}.txt"
done
это было бы очень просто:
paste user_count_*.txt | column -tn
Вы можете попробовать следующий метод
for i in `cat serverlist`
do
echo " "| sed "s/.*/====================================/g"
echo $i
ssh -o 'StrictHostKeyChecking no' $i -A "cat /etc/passwd| awk -F ':' '{print $1}'">$i_host_username_details.txt
done
paste *_host_username_details.txt
Сложный бит в этом вопросе на самом деле заключается в форматировании вывода в столбцах.
Предположим, у вас есть файл с|
-разделенными столбцами, и вы хотите добавить к нему новый столбец. Если вы используете paste
как
paste -d '|' file newdata
и ваш файл не имеет той же длины, что и существующий файл, количество столбцов в выходных данных будет другим, а добавление дополнительных столбцов может сделать его еще хуже. Чтение конечного результата было бы трудно сделать правильно.
Вместо этого вот awk
программа, которая читает существующий файл и добавляет данные, прочитанные из стандартного ввода, в новый столбец этого файла. Вывод будет иметь фиксированное количество столбцов, от первой строки до последней, независимо от того, содержат ли новые данные столбца меньше или больше строк, чем существующие данные.
BEGIN { OFS = FS }
FNR == 1 {
# We assume that all lines have the same number of columns.
nf = NF
}
{
# Read new column from stdin (clear col if failing).
if ((getline col <"/dev/stdin") != 1)
col = ""
# Add new column (possibly empty) and print.
$(nf + 1) = col
print
}
END {
# We only need to do something here if the new column
# data is longer than the existing data.
$0 = "" # Clear current line.
# Add data from stdin until there is no more to read.
while ((getline col <"/dev/stdin") == 1) {
$(nf + 1) = col
print
}
}
Хорошо, давайте воспользуемся этим, чтобы создать небольшой сценарий оболочки, который будет подключаться по SSH к ряду серверов, имена которых перечислены в файле, и извлекать пользователей из файла /etc/passwd
на каждом:
#!/bin/sh
outfile=/tmp/outfile
serverlist=servers.list
tmpfile=$( mktemp )
while read -r server; do
ssh -n "$server" cat /etc/passwd |
cut -d : -f 1 |
{
echo '****************'
printf '%s\n\n' "$server"
cat
} |
awk -F '|' -f append_column.awk "$tmpfile" >"$outfile"
cp "$outfile" "$tmpfile"
done <"$serverlist"
awk -F '|' '{ for (i=1; i<=NF; ++i) $i = sprintf("%-20s", $i); print }' "$tmpfile" >"$outfile"
rm -f "$tmpfile"
Здесь append_column.awk
— это файл, состоящий из программы awk
в верхней части этого ответа.
Сценарий считывает файл $serverlist
в цикле и вызывает ssh -n
, чтобы получить файл /etc/passwd
. Параметр -n
необходим с ssh
, так как в противном случае ssh
будет считываться из того же файла $serverlist
при повторении цикла.
Имена пользователей извлекаются с помощью cut
.
Бит {... }
выводит короткий заголовок, а затем передает имена пользователей без изменений через вызов cat
.
Программа awk
используется для добавления столбцов в выходной файл путем чтения из временного файла (, который будет содержать собранный до сих пор результат ), и результирующие данные копируются обратно во временный файл.
После окончания цикла файл в $tmpfile
(, а также $output
на самом деле )будет содержать нужные данные в виде|
-полей с разделителями. Чтобы очистить это,мы вызываем еще один сценарий Short in -line awk
, который форматирует столбцы выходного файла с выравниванием по левому краю -и текстовыми полями длиной 20 символов.