Bash,命令作为功能不起作用,但手动就可以了

Bash,命令作为功能不起作用,但手动就可以了

我需要将 mysql 转储从远程计算机保存到本地文件,因此通过连接ssh到远程计算机,mysqldump在远程计算机上运行并将其保存到运行脚本的本地文件。

我有 2 个 bash 脚本,function.sh以及export-db.sh1 个配置文件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,但是你真的真的不想去那里。)

相关内容