shell向rman传变量唯一可靠方式是拼接脚本或用here document动态生成,using仅限allocate channel/send中传递mml参数,不支持shell变量;需注意引号、转义及环境变量继承问题。
shell里怎么把变量传进rman脚本
rman本身不解析shell变量,using语法也不是给shell用的——它只在rman内部执行run块时传递参数给allocate channel或send这类命令。想从shell往rman里传路径、日期、dbid这些值,唯一可靠方式是拼接rman脚本内容,或用here document动态生成。
常见错误现象:RMAN-00571: RMAN-00569: Error while parsing command,往往是因为Shell变量没展开、引号嵌套错乱,或者USING被误用在CONNECT或BACKUP顶层语句上。
- 用
cat 方式生成脚本,变量用<code>$VAR直接插入(注意单引号会禁用变量展开,必须用双引号或不加引号) - 避免在RMAN脚本里写
USING '$BACKUP_DIR'——这不会生效;正确写法是Shell先拼好整段RMAN命令,再喂给rman进程 - 如果变量含空格或特殊字符(比如路径带空格),在Shell侧用
"$VAR"包裹,在RMAN脚本内用单引号引用(如FORMAT '/u01/backup/${DATE}_full_%U'→ 实际生成为FORMAT '/u01/backup/20240520_full_%U')
RMAN中USING到底能干啥
USING只在RMAN的ALLOCATE CHANNEL和SEND命令中合法,作用是向介质管理器(如NetBackup、DataDomain)传递运行时参数,不是通用变量机制。它不支持字符串拼接、不读环境变量、也不能用于BACKUP或COPY语句的FORMAT字段。
典型使用场景:调用第三方MML时传token、超时时间、策略名。例如:ALLOCATE CHANNEL c1 DEVICE TYPE 'SBT_TAPE' PARMS 'SBT_LIBRARY=/usr/lib/libddobk.so, ENV=(NSR_SERVER=backup01)'; SEND 'NSR_CLIENT=oraprod, NSR_POLICY=ORACLE_FULL';——这里的SEND后面才是USING的合法位置(但实际常省略USING关键字,直接跟字符串)。
-
USING后只能跟字面量或RMAN内置变量(如&1),不能跟$ORACLE_SID这种Shell变量 - 误写
BACKUP DATABASE FORMAT USING '$DIR/%U';→ 语法错误,RMAN根本不认 - 真正需要动态路径,必须由Shell生成完整
FORMAT '/path/to/...'再喂进去
环境变量在RMAN里为啥有时“看不见”
RMAN子进程默认继承父Shell的环境变量,但有两个关键例外:一是用rman target /走操作系统认证时,若启用了oracle用户限制(如/etc/security/limits.conf),部分变量可能被清空;二是通过sudo -u oracle rman调用时,非登录shell不会加载~oracle/.bash_profile,导致$ORACLE_HOME等未设。
常见错误现象:RMAN-04006: error from auxiliary database: ORA-12162: TNS:net service name is incorrectly specified,本质是$ORACLE_SID或$TNS_ADMIN没传进去。
- 显式导出关键变量:
export ORACLE_SID=prod; export ORACLE_HOME=/u01/app/oracle/product/19c/dbhome_1,再运行rman - 避免用
sudo -u oracle,改用su - oracle -c "rman target / @backup.rman"(-表示登录shell,会加载profile) - 在RMAN脚本开头加
HOST 'echo $ORACLE_SID';调试,确认变量是否可达
动态日期和序列号怎么安全嵌入备份名
直接用date +%Y%m%d拼接容易出问题:Shell命令替换发生在RMAN启动前,但RMAN内部%U、%T等格式符是在备份执行时由Oracle服务端生成的,两者生命周期不同。混用会导致命名冲突或重复覆盖。
正确做法是分层控制:Shell负责“大粒度”区分(如日级别目录),RMAN负责“小粒度”唯一性(如%U保证文件名不重)。不要试图让Shell生成%U的值。
- 推荐格式:
FORMAT '/backup/${ORACLE_SID}/full_$(date +\%Y\%m\%d)/%U'(注意%要转义,否则Shell会尝试解析) - 避免
FORMAT '/backup/$ORACLE_SID/$(date +%Y%m%d)_$RANDOM_%U'——$RANDOM在Shell展开时就固定了,失去随机性意义 - 若需归档日志按小时切片,用RMAN原生
FROM TIME 'SYSDATE-1/24'比Shell算时间更准,不受时区/夏令时影响
最易被忽略的一点:RMAN脚本里的单引号会屏蔽所有变量和命令替换,双引号才能让$()和$VAR生效——但双引号里又得小心$和\的转义层级。写完务必用echo预览生成的RMAN命令流,别靠猜。










