IP как элемент массива Linux выдает UnknownHostException, но как константа работает - PullRequest
0 голосов
/ 06 мая 2019

У меня есть следующий скрипт в каталоге /home/test/javacall, который анализирует CSV пары IP, вызывает sh-файл, который вызывает исполняемый файл jar для получения вывода с этих IP-адресов.

В приведенном ниже коде ip1=${IPArray[0]}бросает UnknownHostException из Java.Но если я использую IP напрямую ip1="10.10.10.10" Java-код работает нормально.Я сделал System.out.println из Java, и я получил тот же IP, отображаемый в обоих случаях.Но только в случае ip1=${IPArray[0]} я получаю исключение.

#!/bin/bash

INPUT="IPPairs.csv"
array=()

while IFS="," read var1 var2 ; do
    echo $var1 $var2
    pairString="$var1***$var2"
    array+=("$pairString")
done < $INPUT

for i in "${array[@]}" ; do
    echo $i
    IPString=$(echo $i | tr '***' ' ')
    read -ra IPArray <<< "$IPString"
    ip1=${IPArray[0]}
    #ip1="10.10.10.10"
    ip2=${IPArray[1]}

    source /home/test/javacall/javacmd.sh "$ip1" "/home/test/javacall/out.txt" "show running-config all-properties"
done

Исключение:

com.jcraft.jsch.JSchException: java.net.UnknownHostException: 10.10.10.10
        at com.jcraft.jsch.Util.createSocket(Util.java:349)
        at com.jcraft.jsch.Session.connect(Session.java:215)
        at com.jcraft.jsch.Session.connect(Session.java:183)

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Эта строка (357 \ 273 \ 277) указывает, что ваш CSV-файл закодирован с помощью Порядок следования байтов (BOM) в начале файла. Команда read не интерпретирует спецификацию как имеющую особое значение, она просто передает необработанные символы, поэтому вы видите их как часть вашего вывода.

Поскольку вы не указали, как генерируется ваш исходный файл, вы можете изменить параметры на этом конце, чтобы предотвратить запись спецификации, что во многих случаях является необязательным. Кроме того, вы можете обойти это различными способами на стороне сценария. Оба эти вопроса предлагают несколько примеров:

Как удалить спецификацию из файла UTF-8?
Команда Cygwin не нашла плохих символов, найденных в .bashrc 357 \ 273 \ 277

Но, честно говоря, если вы просто последуете совету Чарльза Даффи и пропустите свой файл через dos2unix перед его разбором, он автоматически очистит его для вас. i.e.:

...
array=()

dos2unix $INPUT

while IFS="," read var1 var2 ; do
...

Или, опираясь на версию Чарльза:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Bash 4.0+ needed" >&2; exit 1;; esac

INPUT="IPPairs.csv"
declare -A pairs=( )

dos2unix $INPUT

while IFS=$',\r' read -r var1 var2 _ ; do
    pairs[$var1]=$var2
done <"$INPUT"

for ip1 in "${!pairs[@]}"; do
  ip2=${pairs[$ip1]}
  # Using printf %q causes nonprintable characters to be visibly shown
  printf 'Processing pair: %q and %q\n' "$ip1" "$ip2" >&2
done

Обратите внимание, что запуск dos2unix в вашем сценарии не обязательно является наилучшим подходом, поскольку файл необходимо преобразовать только один раз. Вообще говоря, это ничего не должно навредить, особенно с таким маленьким файлом. Тем не менее, лучшим подходом было бы запустить dos2unix как часть любого процесса, отправляющего ваш csv на сервер, и исключить его из этого сценария.

1 голос
/ 12 мая 2019

System.out.println() показывает только видимых символов.

Если ваш входной файл содержит новые строки DOS, System.out.println() не будет их показывать, но они все равно будут присутствовать в вашей командной строке и будут анализироваться как часть IP-адреса для подключения, вызывая исключение UnknownHostException. Преобразование его в текстовый файл UNIX, например dos2unix или использование :set fileformat=unix в vim, обычно является самым быстрым способом исправить это.

Кстати, если вам не нужно сохранять порядок, ассоциативный массив обычно является более подходящей структурой данных для хранения пар:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Bash 4.0+ needed" >&2; exit 1;; esac

declare -A pairs=( )

while IFS=$',\r' read -r var1 var2 _ ; do
    pairs[$var1]=$var2
done <"$input"

for ip1 in "${!pairs[@]}"; do
  ip2=${pairs[$ip1]}
  # Using printf %q causes nonprintable characters to be visibly shown
  printf 'Processing pair: %q and %q\n' "$ip1" "$ip2" >&2
done

В приведенном выше примере IFS=$',\r' предотвращает превращение символов LF (из последовательности "CRLF", которая составляет новую строку DOS) в часть var1 или var2. (Добавление переменной-заполнителя _ для использования любого дополнительного содержимого в данной строке файла добавляет дополнительную страховку к этому пункту).

...