Распечатать вывод цикла SSH По столбцам

Кажется, что то, что вы делаете, определенно будет очень медленным, поскольку каждый раз, когда вы 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
1
08.03.2019, 14:05
3 ответа

Если вы вместо

>> /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
2
27.01.2020, 23:22

Вы можете попробовать следующий метод

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
0
27.01.2020, 23:22

Сложный бит в этом вопросе на самом деле заключается в форматировании вывода в столбцах.

Предположим, у вас есть файл с|-разделенными столбцами, и вы хотите добавить к нему новый столбец. Если вы используете 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 символов.

1
27.01.2020, 23:22

Теги

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