Owe*_*ker 3 io-redirection shell-script echo stdout
我有一个 shell 脚本,它很高兴地完成我所有的备份过程并将进度写入 stderr 和 stdout,只有一个例外——最后一行不会写入我的终端(如果我手动调用脚本),直到我点击Enter.
现在这没什么大不了的,但它没有这样做真的让我很恼火,所以我想了解它为什么会这样。
写入输出的内容(在我点击之后Enter)读取:
[blackero@XXXXXXXXXXXXXXXX ~]$ fullbackup.sh
Tue Feb 28 17:57:41 GMT 2012
Tue Feb 28 17:57:41 GMT 2012
Starting SITE_NAME backup
maintenance_mode was set to 1. [success]
/home/blackero/bin/fullbackup.sh: line 36: hash: lzma: not found
maintenance_mode was set to 0. [success]
Backup for SITE_NAME created
[blackero@XXXXXXXXXXXXXXXX ~]$
Run Code Online (Sandbox Code Playgroud)
脚本的相关部分如下(?
表明我已经对代码进行了自动换行以提高可读性):
#!/bin/bash
date
date 2>&1
# [A bunch of content has been deleted from here]
# Compress with lzma if available, otherwise use gzip
if hash lzma; then
lzma -c ${backup_dest}/${dbname} >${backup_dest}/${dbname}.lzma
? && rm ${backup_dest}/${dbname}
else
gzip -c ${backup_dest}/${dbname} >${backup_dest}/${dbname}.gz
? && rm ${backup_dest}/${dbname}
fi
# Disable maintenance mode.
drush -r ${drupal_root} vset --always-set maintenance_mode 0
# Remove old backups >30 days
find ${backup_dest} -mtime +30 -exec rm {} \; >> /dev/null 2>&1
echo "Backup for ${sitename} created"
echo
echo 2>&1
Run Code Online (Sandbox Code Playgroud)
因此,您可以看到if hash lzma; then
导致该hash: lzma: not found
行进入 stderr的行(如果我可以取消此消息就好了,这样它就不会写出该警告,但我可以忍受)。您可以看到drush
正在将maintenance_mode was set to 0.
行写入标准输出。但是这条线Backup for SITE_NAME created
只有在我点击 时才会出现Enter。
那是因为上一个命令将 stdout 重定向到/dev/null
? 我需要以某种方式撤消该重定向吗?(我认为流重定向只会以原子方式影响单个命令。)
(注意:Fwiw,当这个脚本从 cron 运行时,stdout 和 stderr 重定向到附加到日志文件,一切都非常愉快地写入日志文件,不需要终端输入。脚本最初来自Drupal 的管理指南:fullsitebackup_drush
;我'已经对其进行了大量编辑,但是lzma
orgzip
代码来自那里。)
如果您的备份文件是只读的,则rm
运行的命令可能find
会提示您确认是否应删除备份文件。您看不到提示,因为您将其重定向到 /dev/null。在Enter您按被读取rm
(和品牌rm
采取了默认的答案,这是不删除文件)。
如果这个假设是正确的,您可以通过以下两种方式之一解决问题。一种是可移植但不安全的,另一种是不可移植但更安全。即使在这种情况下,安全差异可能很小(因为攻击者可能无法在 ${backup_dest} 中创建符号链接),但我会建议两种选择:
安全的:
find "${backup_dest}" -depth -mtime +30 -delete
Run Code Online (Sandbox Code Playgroud)
便携的:
find "${backup_dest}" -depth -mtime +30 \
'(' '(' -type d -exec rmdir {} \; -true ')' -o -exec rm -f {} \; ')'
Run Code Online (Sandbox Code Playgroud)
最后,没有必要使用“>> /dev/null”代替“> /dev/null”,因为附加到字符设备和写入它之间没有区别,因为字符设备是不可查找的。
归档时间: |
|
查看次数: |
517 次 |
最近记录: |