知识屋:更实用的电脑技术知识网站
所在位置:首页 > 操作系统 > linux

scp的prompt为啥隐藏不掉

发布时间:2014-09-05 14:05:26作者:知识屋

scp的prompt为啥隐藏不掉
 
把scp的标准输出和标准错误都重定向到一个文件,为什么shell界面还能打出"Enter windows password:"的字符串呢? 
scp fromfilename username@x.x.x.x:/topath/tofilename 2>&1 > /tmp/tmp.txt 
Enter windows password: 
 
查了openssh的代码,答案很明显了。 
char * 
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) 
ssize_t nr; 
int input, output, save_errno; 
char ch, *p, *end; 
struct termios term, oterm; 
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; 
struct sigaction savetstp, savettin, savettou, savepipe; 
 
/* I suppose we could alloc on demand in this case (XXX). */ 
if (bufsiz == 0) { 
errno = EINVAL; 
return(NULL); 
 
restart: 
signo = 0; 
/* 
* Read and write to /dev/tty if available.  If not, read from 
* stdin and write to stderr unless a tty is required. 
*/ 
if ((flags & RPP_STDIN) || 
    (input = output = open(_PATH_TTY, O_RDWR)) == -1) { 
if (flags & RPP_REQUIRE_TTY) { 
errno = ENOTTY; 
return(NULL); 
input = STDIN_FILENO; 
output = STDERR_FILENO; 
 
/* 
* Catch signals that would otherwise cause the user to end 
* up with echo turned off in the shell.  Don't worry about 
* things like SIGXCPU and SIGVTALRM for now. 
*/ 
sigemptyset(&sa.sa_mask); 
sa.sa_flags = 0; /* don't restart system calls */ 
sa.sa_handler = handler; 
(void)sigaction(SIGALRM, &sa, &savealrm); 
(void)sigaction(SIGHUP, &sa, &savehup); 
(void)sigaction(SIGINT, &sa, &saveint); 
(void)sigaction(SIGPIPE, &sa, &savepipe); 
(void)sigaction(SIGQUIT, &sa, &savequit); 
(void)sigaction(SIGTERM, &sa, &saveterm); 
(void)sigaction(SIGTSTP, &sa, &savetstp); 
(void)sigaction(SIGTTIN, &sa, &savettin); 
(void)sigaction(SIGTTOU, &sa, &savettou); 
 
/* Turn off echo if possible. */ 
if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { 
memcpy(&term, &oterm, sizeof(term)); 
if (!(flags & RPP_ECHO_ON)) 
term.c_lflag &= ~(ECHO | ECHONL); 
#ifdef VSTATUS 
if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) 
term.c_cc[VSTATUS] = _POSIX_VDISABLE; 
#endif 
(void)tcsetattr(input, _T_FLUSH, &term); 
} else { 
memset(&term, 0, sizeof(term)); 
term.c_lflag |= ECHO; 
memset(&oterm, 0, sizeof(oterm)); 
oterm.c_lflag |= ECHO; 
 
if (!(flags & RPP_STDIN)) 
(void)write(output, prompt, strlen(prompt));
         end = buf + bufsiz - 1; 
for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '/n' && ch != '/r';) { 
if (p < end) { 
if ((flags & RPP_SEVENBIT)) 
ch &= 0x7f; 
if (isalpha(ch)) { 
if ((flags & RPP_FORCELOWER)) 
ch = tolower(ch); 
if ((flags & RPP_FORCEUPPER)) 
ch = toupper(ch); 
*p++ = ch; 
 
scp会运行一个ssh子进程来完成连接鉴权. 
13996 root       0:00 /usr/local/bin/ssh -x -oForwardAgent no -oPermitLocalCommand no -oClearAllForwardings yes -lusername x.x.x.x scp -t /topath/tofilename 
root@444444[]:/proc/13996/fd> ls -lrt 
total 0 
lrwx------    1 root     root            64 Jan  4 04:12 9 -> /tmp/lock/lock9997 
lrwx------    1 root     root            64 Jan  4 04:12 6 -> /dev/tty 
lrwx------    1 root     root            64 Jan  4 04:12 5 -> socket:[158339] 
lrwx------    1 root     root            64 Jan  4 04:12 4 -> socket:[158338] 
lrwx------    1 root     root            64 Jan  4 04:12 3 -> socket:[160359] 
lrwx------    1 root     root            64 Jan  4 04:12 2 -> /dev/pts/0 
l-wx------    1 root     root            64 Jan  4 04:12 1 -> pipe:[160353] 
lr-x------    1 root     root            64 Jan  4 04:12 0 -> pipe:[160352] 
 
从此可知,ssh就是通过file descriptor 6直接写/dev/tty来把prompt显示到shell界面的,和标准输出1/标准错误2没有任何关系。 
lrwx------    1 root     root            64 Jan  4 04:12 6 -> /dev/tty
 
(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜