Я хотел бы управлять сценарием bash следующим образом:
#!/bin/sh
USER1=_parsefromfile_
HOST1=_parsefromfile_
PW1=_parsefromfile_
USER2=_parsefromfile_
HOST2=_parsefromfile_
PW2=_parsefromfile_
imapsync \
--buffersize 8192000 --nosyncacls --subscribe --syncinternaldates --IgnoreSizeErrors \
--host1 $HOST1 --user1 $USER1 --password1 $PW1 --ssl1 --port1 993 --noauthmd5 \
--host2 $HOST2 --user2 $USER2 --password2 $PW2 --ssl2 --port2 993 --noauthmd5 --allowsizemismatch
с параметрами из контрольного файла, например:
host1 user1 password1 host2 user2 password2
anotherhost1 anotheruser1 anotherpassword1 anotherhost2 anotheruser2 anotherpassword2
где каждая строка представляет один запуск сценария с извлеченными параметрами и преобразованными в переменные.
какой способ сделать это наиболее элегантно?
PAT
В сценариях оболочки это обычно выполняется с помощью source
функция, которая выполняет файл как сценарий оболочки, как если бы он был встроен в сценарий, который вы запускаете - это означает, что любые переменные, которые вы устанавливаете в файле, экспортируются в ваш сценарий.
Обратной стороной является то, что (а) ваш файл конфигурации выполняется, поэтому это представляет угрозу безопасности, если непривилегированные пользователи могут редактировать привилегированные файлы конфигурации. И (б) синтаксис вашего файла конфигурации ограничен допустимым синтаксисом bash. Тем не менее, это ДЕЙСТВИТЕЛЬНО удобно.
config.conf
USER=joe
PASS=hello
SERVER=127.0.0.2
script.sh
#!/bin/bash
# Set defaults
USER=`whoami`
# Load config values
source config.conf
foobar2000 --user=$USER --pass=$PASS --HOST=$HOST
source
можно сократить до одного .
- так что следующие два эквивалентны:
source file.sh
. file.sh
Что-то вроде этого. Важный бит - это использование читать чтобы захватить строку как массив.
#!/bin/bash
configfile=/pathtocontrolfile
cat $configfile | while read -a HR ; do
[[ -z ${HR[0]} ]] && continue # skip empty lines
USER1=${HR[0]}
HOST1=${HR[1]}
PW1=${HR[2]}
USER2=${HR[3]}
HOST2=${HR[4]}
PW2=${HR[5]}
imapsync \
--buffersize 8192000 --nosyncacls --subscribe --syncinternaldates --IgnoreSizeErrors \
--host1 $HOST1 --user1 $USER1 --password1 $PW1 --ssl1 --port1 993 --noauthmd5 \
--host2 $HOST2 --user2 $USER2 --password2 $PW2 --ssl2 --port2 993 --noauthmd5 --allowsizemismatch
done
Я думаю, вам следует использовать что-то вроде getopts, если вы хотите сделать свой сценарий интеллектуальным, вместо того, чтобы просто пытаться читать ваши аргументы на основе чисел.
Что-то вроде этого.
#!/bin/bash
while getopts ":a" opt; do
case $opt in
a)
echo "-a was triggered!" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
$ ./go_test.sh -a
-a was triggered!
$
Вы также можете разбирать аргументы. Вы можете прочитать более подробную информацию об учебнике на Вот.
Я нашел здесь рабочее решение: https://af-design.com/2009/07/07/loading-data-into-bash-variables/
if [ -f "$SETTINGS_FILE" ];then
. "$SETTINGS_FILE"
fi