Портативно/стандартно (POSIX, Unix (SUS) и Linux (LSB) стандарты) и эффективно, Вы записали бы это:
find . \( -name '*.cc' -o -name '*.CC' -o -name '*.[cChH]' \) \
-type f -exec grep -n -- "$1" /dev/null {} +
Наиболее важный момент здесь должен использовать +
вместо ;
. Иначе Вы выполните одну команду grep на файл.
-H
опцией является конкретный GNU, но добавление /dev/null
(который удостоверяется grep
добирается по крайней мере два файла для заглядывания) гарантирует, что grep отображает имя файла.
Вам будет нужно "-", если Вы не сможете удостовериться это $1
никогда не будет запускаться с -
.
Добавление -type f
здесь, чтобы не изучать нерегулярные файлы (как каталоги), но поскольку это означает, что также исключает символьные ссылки, можно хотеть пропустить его.
Вместо того, чтобы вводить пароль несколько раз, вы можете использовать pssh
и его переключатель -A
, чтобы запросить его один раз, а затем передать пароль всем серверам в список.
ПРИМЕЧАНИЕ. Использование этого метода не позволяет использовать ssh-copy-id
, однако вам нужно будет применить свой собственный метод для добавления файла ключа публикации SSH в файл ~ / .ssh / authorized_keys
вашей удаленной учетной записи.
Вот пример, который выполняет задание:
$ cat ~/.ssh/my_id_rsa.pub \
| pssh -h ips.txt -l remoteuser -A -I -i \
' \
umask 077; \
mkdir -p ~/.ssh; \
afile=~/.ssh/authorized_keys; \
cat - >> $afile; \
sort -u $afile -o $afile \
'
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 23:03:58 [SUCCESS] 10.252.1.1
[2] 23:03:58 [SUCCESS] 10.252.1.2
[3] 23:03:58 [SUCCESS] 10.252.1.3
[4] 23:03:58 [SUCCESS] 10.252.1.10
[5] 23:03:58 [SUCCESS] 10.252.1.5
[6] 23:03:58 [SUCCESS] 10.252.1.6
[7] 23:03:58 [SUCCESS] 10.252.1.9
[8] 23:03:59 [SUCCESS] 10.252.1.8
[9] 23:03:59 [SUCCESS] 10.252.1.7
Приведенный выше сценарий обычно имеет такую структуру:
$ cat <pubkey> | pssh -h <ip file> -l <remote user> -A -I -i '...cmds to add pubkey...'
pssh
подробности cat
выводит файл открытого ключа в pssh
pssh
использует переключатель -I
для приема данных через STDIN -l <удаленный пользователь>
- это учетная запись удаленного сервера (мы предполагаем, что у вас одно и то же имя пользователя на всех серверах в IP-файле) -A
сообщает pssh
запросить ваш пароль, а затем повторно использовать его для всех серверов, к которым он подключается to -i
указывает pssh
отправлять любой вывод в STDOUT, а не сохранять его в файлах (поведение по умолчанию) '... cmds для добавления pubkey ...'
- это самая сложная часть того, что происходит, поэтому я разберу это отдельно (см. Ниже) Это команды, которые pssh
будет запускаться на каждом сервере:
' \
umask 077; \
mkdir -p ~/.ssh; \
afile=~/.ssh/authorized_keys; \
cat - >> $afile; \
sort -u $afile -o $afile \
'
В порядке:
установите umask удаленного пользователя на 077, это значит, что для любых каталогов или файлов, которые мы собираемся создать, будут установлены соответствующие разрешения, например так:
$ ls -ld ~ / .ssh ~ / .ssh / authorized_keys
drwx ------ 2 remoteuser remoteuser 4096 21 мая, 22:58 /home/remoteuser/.ssh{{1 }} - rw ------- 1 remoteuser remoteuser 771 21 мая 23:03 /home/remoteuser/.ssh/authorized_keys
создать каталог ~ / .ssh
и проигнорируйте предупреждение, если оно уже есть
$ afile
, указав путь к файлу авторизованных ключей cat - >> $ afile
- принять входные данные из STDIN и добавить в author_keys файл sort -u $ afile -o $ afile
- однозначно сортирует файл authorized_keys и сохраняет его НЕ E: Этот последний бит предназначен для обработки случая, когда вы запускаете вышеуказанное несколько раз на одних и тех же серверах. Это избавит вас от многократного добавления вашего pubkey.
Также обратите особое внимание на то, что все эти команды заключены в одинарные кавычки. Это важно, поскольку мы не хотим, чтобы $ afile
оценивался до тех пор, пока он не будет запущен на удаленном сервере.
' \
..cmds... \
'
Я расширил приведенное выше, чтобы его было легче читать, но обычно я запускаю все в одной строке, например:
$ cat ~/.ssh/my_id_rsa.pub | pssh -h ips.txt -l remoteuser -A -I -i 'umask 077; mkdir -p ~/.ssh; afile=~/.ssh/authorized_keys; cat - >> $afile; sort -u $afile -o $afile'
Используя pssh
, вы можете отказаться от для создания файлов и предоставления динамического содержимого с помощью -h <(... some command ...)
, либо вы можете создать список IP-адресов с помощью другого переключателя pssh
, -H "ip1 ip2 ip3"
.
Например:
$ cat .... | pssh -h <(grep -A1 dp15 ~/.ssh/config | grep -vE -- '#|--') ...
Вышеупомянутое можно использовать для извлечения списка IP-адресов из моего файла ~ / .ssh / config
. Конечно, вы также можете использовать printf
для генерации динамического содержимого:
$ cat .... | pssh -h <(printf "%s\n" srv0{0..9}) ....
Например:
$ printf "%s\n" srv0{0..9}
srv00
srv01
srv02
srv03
srv04
srv05
srv06
srv07
srv08
srv09
Вы также можете использовать seq
для генерации последовательностей форматированных чисел!
pssh
Если вы не хотите использовать pssh
, как я сделал это выше, доступны другие варианты.
У вас есть два варианта:
Вы можете создать файл со всеми IP-адресами серверов, затем выполните следующую
во время чтения -R IP; сделать
ssh-copy-id -i .ssh / id_rsa.pub $ ip
сделано
Предполагая Servers.txt
- это файл с IPS / хостами.
Вы можете поставить все свои IPS / хосты в цикле и запустите SSH-COPE-ID
Как приведено ниже:
для i в Hostname1 HostName2
DO SSH-COPY-ID -I .ssh / id_rsa.pub $ i
Выполнено
Альтернативно используя xargs
, sshpass
и ssh-copy-id
:
Предположим, что ваши учетные данные живут в мандатах. txt в формате user:password@server
:
$ cat credentials.txt
root:insecure@192.168.0.1
foo:insecure@192.168.0.2
bar:realsecure@192.168.0.3
Вы можете сделать:
tr ':@' '\n' < credentials.txt \
| xargs -L3 sh -c 'sshpass -p $1 ssh-copy-id $0@$2'
Примечание: Не забудьте удалить credentials.txt после использования!
ClusterSSH дает вам окно на каждой машине и с общим окном для управления всеми окнами.
Если мы говорим о 10 машинах, то это сработает. Если мы говорим о 100 машинах, то будет много окон.
Прелесть ClusterSSH заключается в том, что если одна машина не на 100% похожа на другую, вы можете просто щелкнуть по окну и отправить нажатия только на эту машину, прежде чем вернуться к отправке нажатий на все машины.
Использовать Ansible довольно просто. Просто замените <ПОЛЬЗОВАТЕЛЬ>
настоящим именем пользователя
$ cd /path/to/public/key
$ cat<<END > hosts
host1.example.com
10.10.10.10
END
$ ansible -i hosts all --ask-pass -u <USER> -m authorized_key \
-a "user=<USER> key='$(cat id_rsa.pub)'"
Пара вещей, которые потенциально могут соответствовать всем требованиям:
Как упоминалось в других ответах, sshpass
, вероятно, является самым простым решением.