Вопрос или проблема
Я на RHEL 6.7 и у меня есть скрипт оболочки korn, который проверяет предварительные требования, подготавливает систему для установки rpm (создает необходимые директории, если их еще нет), останавливает службы, устанавливает rpm и снова запускает службы. Все работает хорошо, пока не начнется установка rpm. 6 из 10 rpm устанавливаются, а затем установка rpm зависает.
Поговорив с владельцем продукта, он сообщил, что предпочел бы, чтобы мы запускали установки rpm в оболочке bash. Поэтому я сделал небольшой скрипт оболочки bash, который устанавливает только rpm, и он прошел успешно.
Теперь, вместо того чтобы полностью изменять мой основной скрипт на bash, я вызываю скрипт bash, который устанавливает rpm, в своем скрипте ksh, и он все еще зависает во время установки rpm.
Есть ли у вас мысли, что может вызывать это?
Вот код, когда установка rpm выполняется внутри ksh
rpm --prefix $MOUNTINST -ivh $BIN/MQSeriesRuntime_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesSDK_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesServer_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesClient_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesSamples_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesJava_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesJRE_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesMan_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesExplorer_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesAMS_6-8.0.0-0.x86_64.rpm \
$BIN/MQSeriesGSKit_6-8.0.0-0.x86_64.rpm 2>&1 | tee /tmp/MQinstV80.out
if_error $? "Установка MQSeries V8.0"
chown mqm:mqm /tmp/MQinstV80.out
if_error $? "Изменение владельца MQinst.out"
Временное решение до того, как IBM предоставит исправление
mkdir $MOUNTINST/logs
chown mqm:mqm $MOUNTINST/logs
chmod 755 $MOUNTINST/logs
А вот образец кода после внесения изменений для запуска скрипта bash внутри скрипта ksh, который прошел успешно при автономном запуске
#rpm --prefix $MOUNTINST -ivh $BIN/MQSeriesRuntime_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesSDK_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesServer_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesClient_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesSamples_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesJava_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesJRE_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesMan_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesExplorer_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesAMS_6-8.0.0-0.x86_64.rpm \
#$BIN/MQSeriesGSKit_6-8.0.0-0.x86_64.rpm 2>&1 | tee /tmp/MQinstV80.out
/var/mqm/trace/WMQUNX8000.00/LINUX/MQV8000GA/6/x86_64/install.sh
#if_error $? "Установка MQSeries V8.0"
#chown mqm:mqm /tmp/MQinstV80.out
#if_error $? "Изменение владельца MQinst.out"
# Временное решение до того, как IBM предоставит исправление
#mkdir $MOUNTINST/logs
#chown mqm:mqm $MOUNTINST/logs
#chmod 755 $MOUNTINST/logs
Я предполагаю много, ваши описания не содержат необходимой информации и вряд ли вводят в заблуждение.
Я бы предположил, что install.sh
— это скрипт, который вы ожидаете запустить в bash, представленный вами как:
a="/var/mqm/trace/WMQUNX8000.00/LINUX/MQV8000GA/6/x86_64/install.sh"
Если это правда, вызовите его так:
/path/to/bash "$a"
Конечно, install.sh должен содержать этот код. Опять же, (вздох)
- предполагая, что if_error может быть реализован функцией if_error в коде ниже.
- $bin — значение папки bin, например
/usr/bin
- У вас нет этой проблемы.
#!/bin/bash
# Если bash не установлен в /bin/bash,
# используйте правильный путь выше.
bin="/usr/bin"
mountinst="некоторое дикое предположение о его значении"
if_error(){
if [[ $1 != 0 ]]; then
shift
echo "$@"
fi
}
rpm --prefix $mountinst -ivh $BIN/MQSeriesRuntime_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesSDK_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesServer_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesClient_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesSamples_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesJava_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesJRE_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesMan_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesExplorer_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesAMS_6-8.0.0-0.x86_64.rpm \
$bin/MQSeriesGSKit_6-8.0.0-0.x86_64.rpm 2>&1 | tee /tmp/MQinstV80.out
if_error "$?" "Установка MQSeries V8.0"
chown "mqm:mqm" "/tmp/MQinstV80.out"
if_error "$?" "Изменение владельца MQinst.out"
# Временное решение до того, как IBM предоставит исправление
mkdir "$mountinst/logs"
chown "mqm:mqm" "$mountinst/logs"
chmod "755" "$mountinst/logs"
Ответ или решение
Вопрос о запуске Bash-скрипта из KornShell (ksh) часто возникает у системных администраторов и разработчиков, поскольку множество скриптов и приложений разрабатывается в различных оболочках. Рассмотрим, как правильно осуществить этот процесс, а также возможные причины, по которым скрипт может зависать во время установки RPM.
Проблема
Как указано в вашем примере, у вас есть KSH-скрипт, который успешно выполняет предустановочные проверки и ряд других операций, но при установке RPM возникает зависание. Генеральный директор продукта порекомендовал использовать Bash для установки RPM, что, по его мнению, будет более надежным.
Когда вы вызываете Bash-скрипт из KSH, он не выполняется так, как предполагается, и это может быть связано с рядом причин:
-
Различия в оболочках: KSH и Bash имеют различные способы обработки некоторых синтаксических конструкций. Это может повлиять на выполнение некоторых команд, особенно если переменные среды или функции обработаны по-разному.
-
Блокировка ввода/вывода: Если ваш скрипт использует команды, требующие ввода с клавиатуры или взаимодействия с пользователем, а это не предусмотрено в KSH, выполнение может зависнуть, ожидая ввода.
-
Уровень прав: Запускаемый Bash-скрипт может требовать других уровней прав доступа, а отсутствующие переменные окружения могут привести к зависанию.
-
Перехват сигналов: При вызове из KSH, Bash-скрипт может не обрабатывать сигналы так же, как это происходит в KSH, что может привести к внезапной остановке.
Решение
Предлагаю исправить вашу реализацию следующим образом:
-
Проверьте путь к Bash: Убедитесь, что Bash установлен по ожидаемому пути. Если у вас установлен Bash в другом месте, необходимо указать его полный путь.
-
Запуск скрипта: Чтобы корректно запустить Bash-скрипт из KSH, используйте данный синтаксис:
/path/to/bash /var/mqm/trace/WMQUNX8000.00/LINUX/MQV8000GA/6/x86_64/install.sh
-
Проверьте переменные окружения: Убедитесь, что все переменные, которым отвечает Bash-скрипт, корректно передаются из KSH. Можете определить переменные в KSH, а затем использовать их в Bash, чтобы избежать пропусков.
-
Дебаг и вывод ошибок: Можете временно включить дополнительный вывод ошибок и логирование в Bash-скрипте для анализа. Добавьте следующую строку в начало скрипта:
set -x # Включить подробный режим отладки
-
Установите блокировку ввода: Если Bash-скрипт ожидает ввод, настройте этот ввод в KSH или преобразуйте его так, чтобы он не ожидал, снижая вероятность зависания.
Пример
Вот так может выглядеть исправленный скрипт на Bash для установки RPM, который будет работать независимо от оболочки:
#!/bin/bash
# Убедитесь, что путь к bash корректный
MOUNTINST="/path/to/mountinst"
BIN="/path/to/bin"
if_error(){
if [[ $1 -ne 0 ]]; then
echo "Ошибка: $2"
exit 1
fi
}
rpm --prefix "$MOUNTINST" -ivh "$BIN/MQSeriesRuntime_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesSDK_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesServer_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesClient_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesSamples_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesJava_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesJRE_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesMan_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesExplorer_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesAMS_6-8.0.0-0.x86_64.rpm" \
"$BIN/MQSeriesGSKit_6-8.0.0-0.x86_64.rpm" 2>&1 | tee /tmp/MQinstV80.out
if_error $? "Установка MQSeries V8.0 завершилась с ошибкой"
chown mqm:mqm /tmp/MQinstV80.out
if_error $? "Ошибка при смене владельца файла"
# Временные действия
mkdir "$MOUNTINST/logs"
chown mqm:mqm "$MOUNTINST/logs"
chmod 755 "$MOUNTINST/logs"
Заключение
Запуск Bash-скрипта из KSH является распространенной задачей, требующей внимательного подхода к устранению возможных проблем. Понимание различий между оболочками, правильная передача переменных окружения и анализ причин зависания установок RPM помогут вам успешно решить возникшие проблемы.