Это используется для проверки условий в сценариях оболочки. Другое название этой программы - test
:
if [ 1 -lt 2 ]; then ...
Это похоже на грамматику оболочки, но на самом деле это не так. Обычно [
- это встроенная оболочка, но, вероятно, в качестве запасного варианта она существует как внешняя команда.
См. Блок «УСЛОВНЫЕ ВЫРАЖЕНИЯ» в man bash
.
Вот как выглядит окончательный сценарий. Я знаю, что это пригодится некоторым из вас.
#!/bin/bash
for host in `cat ip_adds2`
do
echo "Hostname:" $host
sudo ssh -t -o BatchMode=yes -o ConnectTimeout=5 $host 'echo IP: `hostname -i`;read junk total used free shared buffers cached junk < <(free -g | grep ^Mem);echo Memory: $total GiB'
echo -e "\n"
done
Я нашел ответ на этот вопрос. Это было связано с экранированием, поэтому я добавил \ перед $1 и $2, как показано ниже:
free -m | grep Mem | awk '{print \$1,\$2}
Это значительно сложнее, чем должно быть. Кроме того, зачем вам запускать ssh
с sudo
? Если вам нужно войти в удаленный режим как root, вы можете сделать это (ssh root@$host
), но очень маловероятно, что вам понадобится запускать ssh с sudo
, если только ваши ключи ssh не принадлежат root. Что является довольно плохой идеей.
Кроме того, в моей системе Arch команда, которую вы, похоже, используете для получения IP-адреса, возвращает UID моего пользователя:
$ ip route get 1
1.0.0.0 via 192.168.1.1 dev enp0s31f6 src 192.168.1.111 uid 1000
cache
$ ip route get 1 | awk '{print $NF;exit}';
1000
Это работает, как и ожидалось, на Ubuntu, которую я тестировал:
$ ip route get 1
1.0.0.0 via 123.456.7.8 dev eth0 src 123.456.7.9
$ ip route get 1 | awk '{print $NF;exit}';
123.456.7.9
Так что, возможно, более переносимая версия состоит в том, чтобы напечатать поле послеsrc
:
$ ip route get 1 | sed -nE 's/.* src ([0-9.]+).*/\1/p'
192.168.1.111
Ошибки, которые вы видели, действительно были из-за цитирования. Поскольку вы запускали ssh $host "command"
, двойные кавычки вокруг command
заставляют оболочку расширять любые переменные, найденные внутри команды (, поэтому такие вещи, как awk $2
и т. д. ). Чтобы избежать этого и передать нераскрытые символы в awk, вам нужно экранировать $
.
Упрощенная версия вашего скрипта:
#!/bin/bash
sshOpts="BatchMode=yes -o ConnectTimeout=5"
echo > ip_info.output
echo ""
while read host; do
printf "Hostname:%s" $host
ssh -o $sshOpts $host "printf 'Hostname: %s\nIP: %s\nMem: %s\n' $host "$(ip route get 1 | sed -nE 's/.* src ([0-9.]+).*/\1/p')" "$(free -m | awk '/Mem/{print $2}')""
done < ip_adds