![Bash,命令作为功能不起作用,但手动就可以了](https://linux22.com/image/167926/Bash%EF%BC%8C%E5%91%BD%E4%BB%A4%E4%BD%9C%E4%B8%BA%E5%8A%9F%E8%83%BD%E4%B8%8D%E8%B5%B7%E4%BD%9C%E7%94%A8%EF%BC%8C%E4%BD%86%E6%89%8B%E5%8A%A8%E5%B0%B1%E5%8F%AF%E4%BB%A5%E4%BA%86.png)
我需要将 mysql 转储从远程计算机保存到本地文件,因此通过连接ssh
到远程计算机,mysqldump
在远程计算机上运行并将其保存到运行脚本的本地文件。
我有 2 个 bash 脚本,function.sh
以及export-db.sh
1 个配置文件export-db-ssc.cfg
文件function.sh
。
#!/bin/bash
cd "$(dirname "${BASH_SOURCE[0]}")"
date_time="$(date "+%Y%m%d-%H%M%S")"
date_time_now="date +%Y%m%d-%H%M%S"
file_name="$(basename "$0")"
file_log="log/${file_name%.*}.log"
email_sender='[email protected]'
email_recipients='[email protected]'
message()
{
if [ $1 = "i" ]
then
echo "`$date_time_now`|sofimon|"$file_name"|$2|info." 2>&1 | tee -a "$file_log"
elif [ $1 = "t" ]
then
echo "`$date_time_now`|sofimon|"$file_name"|$2|true." 2>&1 | tee -a "$file_log"
else [ $1 = "f" ]
echo "`$date_time_now`|sofimon|"$file_name"|$2|false!" 2>&1 | tee -a "$file_log"
fi
}
# $1 = description, $2 = command, $3 = command if $2 is true, $4 = command if $2 is false
doit()
{
if
$2
then
message "t" "$1"
"$3"
else
message "f" "$1"
result="false"
"$4"
fi
}
email()
{
cat "$file_log" | mail -a "From: sofimon <$email_sender>" -a "Content-type: text/plain" -s "sofimon" -r $email_sender $email_recipients
mv "$file_log" "$file_log"-"$date_time"
rm -rf "$file_log"
}
# Check if run file exists, if so, then exit
if [ -f "$file_log" ]
then
exit 1
fi
> "$file_log"
文件export-db.sh
。
#!/bin/bash
source function.sh
folder_export="/mnt/export"
username="sofimon"
divider=";"
# Read config file, variables as var divided by ;
while IFS=$divider read -ra var; do
command_mkdir="mkdir -p "$folder_export"/"${var[0]}""
command_mysqldump="sudo mysqldump -uroot -p"${var[1]}" --max_allowed_packet=2147483648 --host=localhost --quote-names --ignore-table=mysql.event --opt --all-databases"
command_ssh="ssh -i id_rsa_sofimon -n "$username"@"${var[0]}" "$command_mysqldump" > "$folder_export"/"${var[0]}"/"$date_time"-"${var[0]}".mysql"
# Check commands
echo $command_mkdir
echo $command_ssh
# Run commands
doit "create export folder "${var[0]}"" "$command_mkdir"
doit "dump database from "${var[0]}"" "$command_ssh"
done <<< $(cat "${file_name%.*}"-$1.cfg | grep -v "#")
email
文件export-db-ssc.cfg
。
# host;password
ssc-osw-web;PASSWORD
当我跑步时
./export-db.sh ssc
它向我展示了这一点。
hosek@osw-backup:~/sofimon$ ./export-db.sh ssc
mkdir -p /mnt/export/ssc-osw-web
ssh -n sofimon@ssc-osw-web sudo mysqldump -uroot -pPASSWORD --max_allowed_packet=2147483648 --host=localhost --quote-names --ignore-table=mysql.event --opt --all-databases > /mnt/export/ssc-osw-web/20200221-110536-ssc-osw-web.mysqldump
20200221-110536|sofimon|export-db.sh|create export folder ssc-osw-web|true.
bash: /mnt/export/ssc-osw-web/20200221-110536-ssc-osw-web.mysqldump: No such file or directory
20200221-110538|sofimon|export-db.sh|dump database from ssc-osw-web|false!
所以command_mkdir
没问题,但command_ssh
不起作用。
为什么会出错No such file or directory
?
当我$command_ssh
在终端中手动运行命令时,它工作得很好。
ssh -n sofimon@ssc-osw-web sudo mysqldump -uroot -pPASSWORD --max_allowed_packet=2147483648 --host=localhost --quote-names --ignore-table=mysql.event --opt --all-databases > /mnt/export/ssc-osw-web/20200221-110536-ssc-osw-web.mysqldump
尝试修改脚本以获得此结果echo $command_ssh
。
ssh -n sofimon@ssc-osw-web "sudo mysqldump -uroot -pPASSWORD --max_allowed_packet=2147483648 --host=localhost --quote-names --ignore-table=mysql.event --opt --all-databases" > /mnt/export/ssc-osw-web/20200221-110536-ssc-osw-web.mysqldump
同样的错误。
谢谢。
更新
具有功能的新代码。
#!/bin/bash
cd "$(dirname "${BASH_SOURCE[0]}")"
date_time="$(date "+%Y%m%d-%H%M%S")"
now="date +%Y%m%d-%H%M%S"
module="$1"
config="$2"
log="log/${module%.*}.log"
email_sender='[email protected]'
email_recipients='[email protected]'
#email_recipients='[email protected] [email protected]'
# Declare functions
message()
{
if [ $1 = "i" ]
then
echo "`$now`|sofimon|"$module"|"$config"|$2|info." 2>&1 | tee -a "$log"
elif [ $1 = "t" ]
then
echo "`$now`|sofimon|"$module"|"$config"|$2|true." 2>&1 | tee -a "$log"
else [ $1 = "f" ]
echo "`$now`|sofimon|"$module"|"$config"|$2|false!" 2>&1 | tee -a "$log"
fi
}
doit()
{
#message "i" "$1"
if
"$1"
then
message "t" "$1"
else
message "f" "$1"
result="false"
fi
#message "i" "$1"
}
email()
{
cat "$log" | mail -a "From: sofimon <$email_sender>" -a "Content-type: text/plain" -s "sofimon" -r $email_sender $email_recipients
}
# Declare module functions
export_db()
{
folder_export="/mnt/export"
username="sofimon"
mkdir -p "$folder_export"/"${var[0]}"
ssh -i id_rsa_sofimon -n "$username"@"${var[0]}" "sudo mysqldump -uroot -p"${var[1]}" --max_allowed_packet=2147483648 --host=localhost --quote-names --ignore-table=mysql.event --opt --all-databases" > "$folder_export"/"${var[0]}"/"$date_time"-"${var[0]}".mysql
}
# Check if run file exists, if so, then exit
if [ -f "$log" ]
then
message "f" "script is still runnning"
exit 1
else
> "$log"
fi
# Read config file, variables as var divided by ' '
while IFS=' ' read -ra var; do
doit "$module"
done <<< $(cat "${module%.*}"-"$config".cfg | grep -v "#")
#email
mv "$log" "$log"_"$date_time"
rm -rf "$log"
但它返回这个。
hosek@osw-backup:~/sofimon$ ./sofimon.sh export-db ssc
./sofimon.sh: line 34: export-db: command not found
20200224-133436|sofimon|export-db|ssc|export-db|false!
hosek@osw-backup:~/sofimon$
export-db
如果声明了函数,为什么?
答案1
这是失败的,因为命令字符串的重定向/mnt/export/ssc-osw-web/20200221-110536-ssc-osw-web.mysqldump
正在远程系统上应用,而您已在本地系统上创建了包含目录。
没有简单的方法可以使用您编写的代码来修复此问题,因为您无法* 在保存命令字符串的变量中嵌入重定向。
(* 我想你可以通过eval
或 通过调用bash -c
,但是你真的真的不想去那里。)