通过 system() 获取 SFTP 命令 运行 的退出代码
Get exit code of SFTP command run by system()
我的程序创建了一个使用 expect 执行 sftp 命令的脚本。该脚本应从 SFTP 服务器下载文件。生成脚本后,我的程序调用系统命令 运行 脚本。遇到错误时脚本应该退出。例如,如果密码错误。我怎样才能得到 sftp 命令返回的错误?
下面是生成 运行 脚本的代码:
downloadFileFromServer()
{
ofstream downloadScript;
string result, command;
downloadScript.open("/temp/download.sh");
downloadScript << "#!/usr/bin/expect -f \n";
downloadScript << "spawn sftp -P " + <port number> +
" " + <user name> +
"@" + <IP> + "\n";
downloadScript << "expect { \ntimeout {\nsend_user \"Permission denied\n\"\nexit\n}\n}\n";
downloadScript << "send \"" + <password> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"cd " + <source directory> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"lcd " + <destination directory> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"get " + <file name> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"exit\n\"\n";
downloadScript << "expect -exact \"$\"""\n";
downloadScript.close();
command = "chmod +x /temp/download.sh && /temp/download.sh";
system(command.c_str());
}
下面是创建的脚本:
#!/usr/bin/expect -f
spawn sftp -P <port numner> <user name>@<IP>
expect "<user name>@<IP>'s password:"
expect {
timeout {
send_user "Permission denied\n"
exit
}
}
send "<password>\n"
expect "sftp>"
send "cd <source directory>\n"
expect "sftp>"
send "lcd <destination directory>\n"
expect "sftp>"
send "get <file name>\n"
expect "sftp>"
send "exit\n"
expect -exact "$"
我希望我的程序能够捕获 "Permission denied" 错误。
所有进程在结束时都设置一个数字退出代码 (0..255)。更改 expect 脚本,以便您可以区分正常结束的脚本(通常退出代码为 0)和错误后的显式 exit
。通过向该行添加参数来执行此操作,例如:
...
send_user "Permission denied\n"
exit 77
...
您可以使用
在 C/C++ 程序中恢复此代码
int wstatus = system(command.c_str());
if (WIFEXITED(wstatus))
int exit_code = WEXITSTATUS(wstatus);
wstatus
由两部分组成,进程的退出代码,以及一些提供有关进程是否 运行 或被中断等信息的标志。使用上述宏来提取信息。
参见 man 3 exit
、man waitpid
。
您需要在检查超时前发送密码
expect "<user name>@<IP>'s password:"
send "<password>\n"
expect {
timeout {
send_user "Permission denied\n"
exit 1
}
"sftp>"
}
send "cd ..."
我希望查找超时或提示,以先到者为准。
我的程序创建了一个使用 expect 执行 sftp 命令的脚本。该脚本应从 SFTP 服务器下载文件。生成脚本后,我的程序调用系统命令 运行 脚本。遇到错误时脚本应该退出。例如,如果密码错误。我怎样才能得到 sftp 命令返回的错误?
下面是生成 运行 脚本的代码:
downloadFileFromServer()
{
ofstream downloadScript;
string result, command;
downloadScript.open("/temp/download.sh");
downloadScript << "#!/usr/bin/expect -f \n";
downloadScript << "spawn sftp -P " + <port number> +
" " + <user name> +
"@" + <IP> + "\n";
downloadScript << "expect { \ntimeout {\nsend_user \"Permission denied\n\"\nexit\n}\n}\n";
downloadScript << "send \"" + <password> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"cd " + <source directory> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"lcd " + <destination directory> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"get " + <file name> + "\n\"\n";
downloadScript << "expect \"sftp>\"""\n";
downloadScript << "send \"exit\n\"\n";
downloadScript << "expect -exact \"$\"""\n";
downloadScript.close();
command = "chmod +x /temp/download.sh && /temp/download.sh";
system(command.c_str());
}
下面是创建的脚本:
#!/usr/bin/expect -f
spawn sftp -P <port numner> <user name>@<IP>
expect "<user name>@<IP>'s password:"
expect {
timeout {
send_user "Permission denied\n"
exit
}
}
send "<password>\n"
expect "sftp>"
send "cd <source directory>\n"
expect "sftp>"
send "lcd <destination directory>\n"
expect "sftp>"
send "get <file name>\n"
expect "sftp>"
send "exit\n"
expect -exact "$"
我希望我的程序能够捕获 "Permission denied" 错误。
所有进程在结束时都设置一个数字退出代码 (0..255)。更改 expect 脚本,以便您可以区分正常结束的脚本(通常退出代码为 0)和错误后的显式 exit
。通过向该行添加参数来执行此操作,例如:
...
send_user "Permission denied\n"
exit 77
...
您可以使用
在 C/C++ 程序中恢复此代码int wstatus = system(command.c_str());
if (WIFEXITED(wstatus))
int exit_code = WEXITSTATUS(wstatus);
wstatus
由两部分组成,进程的退出代码,以及一些提供有关进程是否 运行 或被中断等信息的标志。使用上述宏来提取信息。
参见 man 3 exit
、man waitpid
。
您需要在检查超时前发送密码
expect "<user name>@<IP>'s password:"
send "<password>\n"
expect {
timeout {
send_user "Permission denied\n"
exit 1
}
"sftp>"
}
send "cd ..."
我希望查找超时或提示,以先到者为准。