У меня есть следующий скрипт в каталоге /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)
Ваш сценарий оболочки не работает. Как же мы узнаем без хрустального шара? Не могли бы вы поделиться текстом вашего сценария оболочки?
Обновленный вопрос со сценарием оболочки.
есть отличия в команде userid pw out.txtuserID "pwd"
#!/bin/bash java -jar /home/myname/Executor.jar 10.10.10.10 userID "pwd" outs1.txt "показать все свойства текущей конфигурации" работает. Но с $s1 не получается.
Что, если вы выполните команду точный из сценария оболочки? java -jar /home/myname/Executor.jar 10.10.10.10 userid pw out.txt "show running-config all-properties"
Когда я помещаю точную команду в качестве единственной строки в файле bash, она работает.
Используйте bash -x, чтобы включить ведение журнала на уровне трассировки. Таким образом, если у вас есть, скажем, новые строки DOS во входном файле, который вы read вводите, они будут отображаться как $'...\r' форматирование в ваших строках в трассировке. (Кстати, проверка на это буквально самая первая запись в разделе «Прежде чем спрашивать о проблемном коде» в stackoverflow.com/tags/bash/info).
Кстати, было бы неплохо запустить код через shellcheck.net и исправить найденные ошибки. Даже такая простая вещь, как echo $i, может вызвать ошибки — см. БашПитфоллы #14 и/или страницу предупреждения shellcheck SC2086.
Кстати, tr '***' ' ' — это точно, то же самое, что и tr '*' ' '; tr работает только с наборами символов; он не знает и не заботится о том, сколько раз показывается экземпляр.
@itsraja Пожалуйста, обновите свой вопрос информацией, которую вы прокомментировали в ответе Чарльза. Вы также должны удалить теги java из своего вопроса, так как проблема явно связана с анализом вашего CSV в Bash.
Может быть, но сохранение тега java поможет тем, кто получает это исключение в среде Linux.




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
Ваш ответ указал направление, и создание CSV-файла в Linux решило проблему.
Другой способ исправить это будет ip1=${ip1#$'\357\273\277'}
Эта строка (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 на сервер, и не допускать его в этот скрипт.
Как вы выполняете скрипт bash?