IP как элемент массива Linux выдает UnknownHostException, но работает как константа

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

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

#!/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)

Как вы выполняете скрипт bash?

Martin Prikryl 06.05.2019 11:12

Ваш сценарий оболочки не работает. Как же мы узнаем без хрустального шара? Не могли бы вы поделиться текстом вашего сценария оболочки?

Gyro Gearless 06.05.2019 11:15

Обновленный вопрос со сценарием оболочки.

itsraja 06.05.2019 12:18

есть отличия в команде userid pw out.txtuserID "pwd"

error404 06.05.2019 12:30

#!/bin/bash java -jar /home/myname/Executor.jar 10.10.10.10 userID "pwd" outs1.txt "показать все свойства текущей конфигурации" работает. Но с $s1 не получается.

itsraja 06.05.2019 12:56

Что, если вы выполните команду точный из сценария оболочки? java -jar /home/myname/Executor.jar 10.10.10.10 userid pw out.txt "show running-config all-properties"

Martin Prikryl 07.05.2019 07:31

Когда я помещаю точную команду в качестве единственной строки в файле bash, она работает.

itsraja 07.05.2019 10:35

Используйте bash -x, чтобы включить ведение журнала на уровне трассировки. Таким образом, если у вас есть, скажем, новые строки DOS во входном файле, который вы read вводите, они будут отображаться как $'...\r' форматирование в ваших строках в трассировке. (Кстати, проверка на это буквально самая первая запись в разделе «Прежде чем спрашивать о проблемном коде» в stackoverflow.com/tags/bash/info).

Charles Duffy 12.05.2019 20:29

Кстати, было бы неплохо запустить код через shellcheck.net и исправить найденные ошибки. Даже такая простая вещь, как echo $i, может вызвать ошибки — см. БашПитфоллы #14 и/или страницу предупреждения shellcheck SC2086.

Charles Duffy 12.05.2019 20:32

Кстати, tr '***' ' ' — это точно, то же самое, что и tr '*' ' '; tr работает только с наборами символов; он не знает и не заботится о том, сколько раз показывается экземпляр.

Charles Duffy 12.05.2019 20:33

@itsraja Пожалуйста, обновите свой вопрос информацией, которую вы прокомментировали в ответе Чарльза. Вы также должны удалить теги java из своего вопроса, так как проблема явно связана с анализом вашего CSV в Bash.

BryKKan 13.05.2019 19:56

Может быть, но сохранение тега java поможет тем, кто получает это исключение в среде Linux.

itsraja 14.05.2019 13:07
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
12
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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. (Добавление переменной-заполнителя _ для использования любого дополнительного контента в данной строке файла добавляет дополнительную страховку к этому моменту).

Когда я использовал команду printf 'Пара обработки: %q и %q\n' "$ip1" "$ip2" >&2 в моем существующем коде, я получил пару обработки: $'\357\273\27710.10.10.10' и 10.10 .10.11

itsraja 13.05.2019 04:00

Ваш ответ указал направление, и создание CSV-файла в Linux решило проблему.

itsraja 14.05.2019 13:03

Другой способ исправить это будет ip1=${ip1#$'\357\273\277'}

Charles Duffy 14.05.2019 13:36

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

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

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

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

...
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 на сервер, и не допускать его в этот скрипт.

Другие вопросы по теме