Я новичок в 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