|
以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出。授予非管理用户执行 xp_cmdshell 的权限。
& W+ w- V* X O# ] # y- A, \9 X7 B8 z% B, X) o7 A! [
说明 在 Microsoft® Windows® 98 操作系统中执行 xp_cmdshell 时,将不把 xp_cmdshell 的返回代码设置为唤醒调用的可执行文件的进程退出代码。返回代码始终为 0。
1 Q7 I* O, e4 Y+ ~$ V! ]* V% V1 u& ]/ Z; c+ A \7 x) w
5 }: d J5 F: b& L' `# @% I
语法% J2 Q! Y" N A$ {
xp_cmdshell {'command_string'} [, no_output] ; Q. }, m& A6 e7 C' }
参数
! ~$ g4 I& V1 h; x7 ]5 c3 j4 u" I& {'command_string' * A( D2 Y5 N% }) m3 G* c; H
是在操作系统命令行解释器上执行的命令字符串。command_string 的数据类型为 varchar(8000) 或 nvarchar(4000),没有默认值。command_string 不能包含一对以上的双引号。如果由 command_string 引用的文件路径或程序名称中有空格,则需要使用一对引号。如果使用嵌入空格不方便,可考虑使用 FAT 8.3 文件名作为解决办法。 # n- q+ x/ N+ k/ {/ r# y
no_output
! m/ T% l1 V. M* Q3 L; }是可选参数,表示执行给定的 command_string,但不向客户端返回任何输出。 - ^9 f* m0 k0 v, v" k" j$ H$ ^2 w
返回代码值$ c/ {3 ^* K; G) a# h C( Y: `
0(成功)或 1(失败) " o5 ]: x/ L9 X' P& |1 I
结果集$ \. S! K6 T+ h; @( C& V4 [
执行下列 xp_cmdshell 语句将返回当前目录的目录列表。 xp_cmdshell 'dir *.exe'
; N* D; T6 i* D" D; d. _; O r( {; D3 r' h. p$ \
行以 nvarchar(255) 列的形式返回。 - L( l3 G3 ~+ G8 m6 P# u6 d
执行下列 xp_cmdshell 语句将返回随后的结果集: xp_cmdshell 'dir *.exe', NO_OUTPUT
0 V: D$ z9 k* c! N( p# t. [( X: n7 Q: c- x" M) @8 ?, n
下面是结果: The command(s) completed successfully. k) |) e: B% D! H0 p P$ h2 l
注释4 Y: ?; L2 J+ D6 y& k
xp_cmdshell 以同步方式操作。在命令行解释器命令执行完毕之前,不会返回控制。 # P/ q V1 M# u6 t `6 T
当授予用户执行权限时,用户能在 Microsoft Windows NT® 命令行解释器上执行运行 Microsoft SQL Server™ 的帐户有权执行的任何操作系统命令。 1 Y# c6 L, f8 Z) r$ h/ N3 g
默认情况下,只有 sysadmin 固定服务器角色的成员才能执行此扩展存储过程。但是,也可以授予其他用户执行此存储过程的权限。
& L2 n) ^2 ]" O: z5 t% c( E当作为 sysadmin 固定服务器角色成员的用户唤醒调用 xp_cmdshell 时,将在运行 SQL Server 服务的安全上下文中执行 xp_cmdshell。当用户不是 sysadmin 组的成员时,xp_cmdshell 将模拟使用 xp_sqlagent_proxy_account 指定的 SQL Server 代理程序的代理帐户。如果代理帐户不能用,则 xp_cmdshell 将失败。这只是针对于 Microsoft® Windows NT® 4.0 和 Windows 2000。在 Windows 9.x 上,没有模拟,且 xp_cmdshell 始终在启动 SQL Server 的 Windows 9.x 用户的安全上下文下执行。
( a* `, a# \, x( C- T / x8 Z6 `: { t# k2 a' e% }, a
说明 在早期版本中,获得 xp_cmdshell 执行权限的用户在 MSSQLServer 服务的用户帐户上下文中运行命令。可以通过配置选项配置 SQL Server,以便对 SQL Server 无 sa 访问权限的用户能够在 SQLExecutiveCmdExec Windows NT 帐户的上下文中运行 xp_cmdshell。在 SQL Server 7.0 中,该帐户称为 SQLAgentCmdExec。现在,不是 sysadmin 固定服务器角色成员的用户将在该帐户上下文中运行命令,而无需再进行配置更改。# s$ E3 Z- f, B8 N9 G. ^ W
% \( W* Y+ c2 L7 J
权限
- s8 Y: k9 O( _; A0 u7 X4 I' z xp_deletemail 的执行权限默认授予 sysadmin 固定服务器角色的成员,但可以授予其他用户。
, q+ |- v. G& _6 V9 }( K. Z Q" F( U6 _: K9 O. ?
重要 如果为 MSSQLServer 服务选用的 Windows NT 帐户不是本地管理员组的成员,则非 sysadmin 固定服务器角色成员的用户将无法执行 xp_cmdshell。
* R9 @. E( C" D6 a0 u
; z* y' o9 p# e2 I" r示例A. 返回可执行文件列表% [% E4 z0 p3 A7 y0 p* c, k
下例显示执行目录命令的 xp_cmdshell 扩展存储过程。 EXEC master..xp_cmdshell 'dir *.exe'5 z9 z* O$ q4 N" E R+ [& p! S
B. 使用 Windows NT net 命令" b5 w: T4 k6 b# f2 [, M
下例显示 xp_cmdshell 在存储过程中的使用。下例先用 net send 通知用户 SQL Server 即将关闭,然后用 net pause 暂停服务器,最后用 net stop 关闭服务器。 CREATE PROC shutdown10
' E1 R2 g# j' _6 pAS
[( \" x% X/ m6 Y: cEXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down \! ?# f+ a% n ~) f$ l* X
in 10 minutes. No more connections allowed.', no_output: s& n- j" L1 S, \8 s6 H
EXEC xp_cmdshell 'net pause sqlserver'
+ R, K6 S, z4 @ W" V kWAITFOR DELAY '00:05:00'6 h/ z H) [8 `# R& F0 U0 }# x
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down
/ c/ S, n: G% K( R; y in 5 minutes.', no_output) N6 _9 V( n! e7 b& S
WAITFOR DELAY '00:04:00' }0 C% p) A- B- R; X
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down 8 x: O- p9 w( N- o, X+ M4 H# E: D
in 1 minute. Log off now.', no_output5 K6 _6 [( D. j$ W9 e
WAITFOR DELAY '00:01:00'& i$ _: u- I0 Z6 A( k
EXEC xp_cmdshell 'net stop sqlserver', no_output4 r g: Z) h7 L
C. 不返回输出
$ E$ _+ ?% Z2 q2 w# B下例使用 xp_cmdshell 执行命令字符串,且不向客户端返回输出。 USE master% m4 b# n+ |* ?
EXEC xp_cmdshell 'copy c:\sqldumps\pubs.dmp \\server2\backups\sqldumps', ( a4 Z5 p( U' V/ }/ k
NO_OUTPUT
1 Y+ Z5 m6 p# H2 `D. 使用返回状态% I6 p+ b1 h* R$ n+ V& n' L3 X
在下例中,xp_cmdshell 扩展存储过程也给出了返回状态。返回代码值存储在变量 @result 中。 DECLARE @result int1 F: ]. B) W9 ^: D @3 n* b
EXEC @result = xp_cmdshell 'dir *.exe'
9 F" @4 N3 F3 MIF (@result = 0)5 P2 _1 d: x H/ I2 z
PRINT 'Success') R1 m0 u! c B
ELSE" S8 H7 `: W8 {4 {! w
PRINT 'Failure'
$ j" p3 X3 S1 p: Q/ SE. 将变量内容写入文件 " I2 T" t- g9 G; g6 l9 y2 y
下例将 @var 变量的内容写入当前服务器目录下名为 var_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname, x0 k$ K( F$ S6 o6 E& A
SET @var = 'Hello world'
6 k3 s: i0 w9 g+ M5 f$ ^) ^SET @cmd = 'echo ' + @var + ' > var_out.txt'
% B! i6 F# r; {* [EXEC master..xp_cmdshell @cmd
0 Z( d1 O& M( X* v: c& `F. 将命令的结果捕获到文件
2 ?/ M9 K9 X# B; Q下例将当前目录的内容写入当前服务器目录中名为 dir_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname
* Z7 Y3 b8 E. M$ e" }SET @var = 'dir/p'
" G* w2 ]& Y% P9 c/ fSET @cmd = @var + ' > dir_out.txt'
% W$ W2 F/ \8 mEXEC master..xp_cmdshell @cmd9 L7 r+ q# x8 t, j0 S( u3 y
$ I/ ^4 q! G0 |$ E- L( e- K+ M' ]9 w: o
请参见
1 A+ t& ^$ b$ l2 ~ / o. B9 c/ Z6 i6 G' D
sqlserver2000/tsqlref/ts_create_4hk5.htm">CREATE PROCEDURE $ S, d7 z2 q' G' e, U5 X/ J! k
sqlserver2000/tsqlref/ts_ea-ez_05ro.htm">EXECUTE / ]; y+ ?# o# g4 x/ m* g
创建安全帐户
# A+ Y' n( _8 l S tsqlserver2000/tsqlref/ts_sp_00_519s.htm">系统存储过程(常规扩展过程)
5 H4 t% x- C3 x, p. i7 r5 [: \; K6 h
9 I9 [" J. c, V* w8 g( }- N& W |