Назад | Перейти на главную страницу

Использование экспорта в Bash Script на CentOS

Я новичок в Linux, и у меня проблемы с тем, что должно быть очень простым сценарием Bash в CentOS.

#! /bin/bash
# script to restore the cognos rds from snapshot
export AWS_RDS_HOME=/opt/aws/apitools/rds
export PATH=$PATH:$AWS_RDS_HOME/bin
export AWS_CREDENTIAL_FILE=$AWS_RDS_HOME/credential-file-path.template
echo $AWS_RDS_HOME
echo $PATH
echo $AWS_CREDENTIAL_FILE
rds-delete-db-instance mydb --final-db-snapshot-identifier mydb-daily-$(date +%Y)-$(date +%m)-$(date +%d) --force -region eu-west-1

Я добавил эхо-выражения, чтобы видеть, что происходит. Результат, когда я бегу с

sh myscript.sh

является:

/opt/aws/apitools/rds
/bin/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin:/opt/aws/apitools/rds
/credential-file-path.template
rds-delete-db-instance: command not found

Таким образом, может показаться, что команды экспорта не работают, когда я ссылаюсь на другие переменные среды, которые были установлены в том же сценарии.

Где я ошибаюсь?

Спасибо

Обновление: я пробовал приведенные ниже предложения, но без радости. Запуск bash -x был интересным. Могут ли за этим стоять символы "\ r" ниже, когда я пытаюсь объединить? например

#! /bin/bash
# test script
export AWS_RDS_HOME=/opt/aws/apitools/rds
export PATH=$PATH:$AWS_RDS_HOME/bin
export AWS_CREDENTIAL_FILE=$AWS_RDS_HOME/credential-file-path.template
echo $AWS_RDS_HOME
echo $PATH
echo $AWS_CREDENTIAL_FILE

Результаты в:

+ export $'AWS_RDS_HOME=/opt/aws/apitools/rds\r'
+ AWS_RDS_HOME=$'/opt/aws/apitools/rds\r'
+ export $'PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin:/opt/aws/apitools/rds\r/bin\r'
+ PATH=$'/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin:/opt/aws/apitools/rds\r/bin\r'
+ export $'AWS_CREDENTIAL_FILE=/opt/aws/apitools/rds\r/credential-file-path.template\r'
+ AWS_CREDENTIAL_FILE=$'/opt/aws/apitools/rds\r/credential-file-path.template\r'
+ echo $'/opt/aws/apitools/rds\r\r'
/opt/aws/apitools/rds
+ echo $'/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin:/opt/aws/apitools/rds\r/bin\r\r'
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home//binuser/bin:/opt/aws/apitools/rds
+ echo $'/opt/aws/apitools/rds\r/credential-file-path.template\r'
/credential-file-path.template

Я использую AMI Amazon Linux по умолчанию на EC2, поэтому с моими настройками не должно быть ничего необычного.

Вы выполняете сценарий, запустив «sh myscript.sh». Если вы вызываете bash с помощью «sh», bash попытается «максимально точно имитировать поведение при запуске исторических версий sh, в то же время соответствуя стандарту POSIX» (согласно странице руководства для bash в разделе «Вызов» ).

Историческая оболочка Bourne не распознает «export VARIABLE = value». Типичный способ экспорта переменных в оболочке Bourne - «VARIABLE = value; export VARIABLE», т.е. установка значения и экспорт - это отдельные команды. Делать все это одной командой - это башизм.

Итак, вы можете попробовать вызвать свой скрипт как «bash myscript.sh», который должен работать (он работает для меня, хотя, по общему признанию, он также работает с вызовом «sh myscript.sh»; где-то может быть что-то смешное с настройками моей оболочки , или что-нибудь смешное в твоем). Вы также можете сделать файл исполняемым с помощью «chmod + x myscript.sh» и просто запустить его напрямую с помощью «./myscript.sh», поскольку он должен вызывать bash, согласно «#!». в первой строке.

Похоже, что в вашем скрипте есть ошибочный возврат каретки в конце каждой строки. Это может произойти, если в какой-то момент своей жизни скрипт редактировался в системе Windows. Вы можете попытаться восстановить его с помощью этой команды:

perl -pi -e 's/\r//' myscript.sh

Из-за ошибочного возврата каретки он не ссылается на каталог rds как ты и задумал, но вместо этого rds за которым следует возврат каретки. Предположительно у вас нет каталога с таким именем, и если предположить, rds-delete-db-instance живет внутри rds каталог, что объясняет, почему вы получаете command not found.

Есть еще несколько проблем с вашим скриптом, которые я попытался исправить здесь:

#!/bin/bash
# script to restore the cognos rds from snapshot
export AWS_RDS_HOME=/opt/aws/apitools/rds
export PATH="$PATH:$AWS_RDS_HOME/bin"
export AWS_CREDENTIAL_FILE="$AWS_RDS_HOME/credential-file-path.template"
echo "$AWS_RDS_HOME"
echo "$PATH"
echo "$AWS_CREDENTIAL_FILE"
rds-delete-db-instance mydb --final-db-snapshot-identifier "mydb-daily-$(date +%Y-%m-%d)" --force -region eu-west-1

Я удалил пробел после #! потому что он обычно не используется, и я считаю, что сценарий немного более переносим без места.

я добавил " вокруг струн, в которых $ используются символы. В " значимы в случае расширения, произведенного с использованием $ содержит любые специальные символы, включая пробелы.

Кроме того, я поменял три date команды в единый. Используя один date команда короче и надежнее, если сценарий запускается незадолго до полуночи.

Когда вы печатаете

sh myscript.sh

вы создаете новую оболочку с новым набором переменных среды. Внутри этой оболочки переменная $ AWS_RDS_HOME будет содержать значение «/ opt / aws / apitools / rds», но этот контекст исчезает при выходе из sh.

Похоже, вы хотите использовать

. myscript.sh

Это «точка», за которой следует «пробел», за которым следует имя файла. Команда «точка» интерпретирует файл аргументов в контексте текущей оболочки, таким образом, экспортированные переменные впоследствии становятся доступными в текущей оболочке.

Хм, попробуйте заключить бит справа от = в двойные (") кавычки? Он работал как с, так и без них в моем небольшом тесте. Хотя его нет в CentOS, но bash должен вести себя одинаково на разных Linux, я думаю .

Это единственный способ, которым это сработало для меня в Centos / с использованием bash.

source myscript.sh

или

. myscript.sh