|
以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出。授予非管理用户执行 xp_cmdshell 的权限。 5 j: a+ s2 |. A+ s
9 @! w5 s" `. i: Q* G说明 在 Microsoft® Windows® 98 操作系统中执行 xp_cmdshell 时,将不把 xp_cmdshell 的返回代码设置为唤醒调用的可执行文件的进程退出代码。返回代码始终为 0。- @2 G% C, _% \% O: }; q' H' O0 X
% h5 E( }6 P1 P5 X3 \5 a: C# H
; h- n- D0 \% g
语法
/ _: C) S G, v( gxp_cmdshell {'command_string'} [, no_output] 6 `+ F* M3 a0 t% I
参数6 u9 a5 E6 J. u b: v" g3 I
'command_string'
& P$ |+ a, o0 X% S0 D* H: q是在操作系统命令行解释器上执行的命令字符串。command_string 的数据类型为 varchar(8000) 或 nvarchar(4000),没有默认值。command_string 不能包含一对以上的双引号。如果由 command_string 引用的文件路径或程序名称中有空格,则需要使用一对引号。如果使用嵌入空格不方便,可考虑使用 FAT 8.3 文件名作为解决办法。 Z+ G2 A( Q3 K w1 N% P% B
no_output ; A1 Z# j; C2 U
是可选参数,表示执行给定的 command_string,但不向客户端返回任何输出。
# w) ?1 `$ G3 d) `9 Q) r返回代码值
' L0 u. n9 x; Q9 l! W3 X8 ]0(成功)或 1(失败) % ~" J7 i7 S! z$ A) r4 g
结果集' O- B- z5 `& E
执行下列 xp_cmdshell 语句将返回当前目录的目录列表。 xp_cmdshell 'dir *.exe'
6 T' O/ D; j6 g1 h% c! r5 U* h, A+ e8 M0 Q
行以 nvarchar(255) 列的形式返回。
/ |& c9 x6 ?9 }! |2 ~8 \7 v3 f# u执行下列 xp_cmdshell 语句将返回随后的结果集: xp_cmdshell 'dir *.exe', NO_OUTPUT. l s. O$ S/ r3 a! u9 K: h
5 v" P- |" g! m5 i3 B
下面是结果: The command(s) completed successfully.
: h. S' r' Z' r1 o( b1 g7 q: F6 {注释
) h7 L% H; Q+ F8 y# J$ V( Mxp_cmdshell 以同步方式操作。在命令行解释器命令执行完毕之前,不会返回控制。 ( Z2 y8 a8 }3 m, k# B
当授予用户执行权限时,用户能在 Microsoft Windows NT® 命令行解释器上执行运行 Microsoft SQL Server™ 的帐户有权执行的任何操作系统命令。 8 ? U9 e, V0 a3 ?1 _, T: w
默认情况下,只有 sysadmin 固定服务器角色的成员才能执行此扩展存储过程。但是,也可以授予其他用户执行此存储过程的权限。
, B( D6 F' x( a" q' n3 q当作为 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 用户的安全上下文下执行。
7 M3 x( k" h/ [
4 I0 S- t' L9 z5 Q& i说明 在早期版本中,获得 xp_cmdshell 执行权限的用户在 MSSQLServer 服务的用户帐户上下文中运行命令。可以通过配置选项配置 SQL Server,以便对 SQL Server 无 sa 访问权限的用户能够在 SQLExecutiveCmdExec Windows NT 帐户的上下文中运行 xp_cmdshell。在 SQL Server 7.0 中,该帐户称为 SQLAgentCmdExec。现在,不是 sysadmin 固定服务器角色成员的用户将在该帐户上下文中运行命令,而无需再进行配置更改。
! f) } t; I; u+ E; J4 N. T- \ A. K
权限
! ~! y& B7 k3 K0 j$ `# z5 U- Q xp_deletemail 的执行权限默认授予 sysadmin 固定服务器角色的成员,但可以授予其他用户。 : f! P) v7 Q4 ~9 l% k0 ?- g
# t# } |9 d# C2 {0 N
重要 如果为 MSSQLServer 服务选用的 Windows NT 帐户不是本地管理员组的成员,则非 sysadmin 固定服务器角色成员的用户将无法执行 xp_cmdshell。- k) g+ ~1 K: f
! g( K0 i6 q& v
示例A. 返回可执行文件列表3 P* F8 J4 U$ ^1 T6 q# ^8 p3 U
下例显示执行目录命令的 xp_cmdshell 扩展存储过程。 EXEC master..xp_cmdshell 'dir *.exe'
' b0 N4 G3 M- EB. 使用 Windows NT net 命令- F, y- t4 j- p% A* w# W9 S
下例显示 xp_cmdshell 在存储过程中的使用。下例先用 net send 通知用户 SQL Server 即将关闭,然后用 net pause 暂停服务器,最后用 net stop 关闭服务器。 CREATE PROC shutdown10
* m- P7 \" E7 i4 f" C! X; JAS
; O7 Y5 k. ?& }4 mEXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down * t- Y4 k; m$ b/ l, @ b0 Z: j
in 10 minutes. No more connections allowed.', no_output
! }# b/ ]! @0 X% J8 w& r, CEXEC xp_cmdshell 'net pause sqlserver'
( C8 e5 k/ n+ I' gWAITFOR DELAY '00:05:00'7 ^* z+ b- C+ }0 v
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server shutting down ' u/ }3 Y8 l4 o
in 5 minutes.', no_output
5 f0 a! Y: j$ K( _4 q& OWAITFOR DELAY '00:04:00': q$ P3 x& e3 {
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server shutting down
' U8 o( n! x) O" N: Z/ h in 1 minute. Log off now.', no_output9 h( }. }- E% {4 J
WAITFOR DELAY '00:01:00'
8 _6 n8 q" j6 I/ B# t; ^- s- sEXEC xp_cmdshell 'net stop sqlserver', no_output r1 i# w; t5 k
C. 不返回输出 " t- r, w& J/ Z( b0 R& P z! g
下例使用 xp_cmdshell 执行命令字符串,且不向客户端返回输出。 USE master0 a. v6 Z* a( v: D. t9 y9 ]
EXEC xp_cmdshell 'copy c:\sqldumps\pubs.dmp \\server2\backups\sqldumps',
4 v+ U/ `5 Z$ k ^2 m NO_OUTPUT, \) _5 e M$ n4 [/ @( b' `* t
D. 使用返回状态
% e7 h. n0 r/ }3 w在下例中,xp_cmdshell 扩展存储过程也给出了返回状态。返回代码值存储在变量 @result 中。 DECLARE @result int5 [; g: x( h$ p# Y+ K: K& \* l: C
EXEC @result = xp_cmdshell 'dir *.exe'
v3 {( M1 n: k& L# p' V. c! HIF (@result = 0)7 [2 L) [3 ?( l
PRINT 'Success'3 t2 P+ y9 G( g8 ^/ ]$ z# C
ELSE
6 h( t) ^2 D d0 x0 b& p; r0 e PRINT 'Failure'* W$ V: ?7 [- m. k
E. 将变量内容写入文件
) e/ k/ Z8 c# q8 R7 ]' c i$ c下例将 @var 变量的内容写入当前服务器目录下名为 var_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname
7 {* g& e, W4 U# G0 O7 T! XSET @var = 'Hello world'
Z; `& y8 W) F: M) tSET @cmd = 'echo ' + @var + ' > var_out.txt'
4 y3 m, z4 z0 r9 jEXEC master..xp_cmdshell @cmd$ R4 S0 @/ j4 v/ V# E$ m8 E
F. 将命令的结果捕获到文件% S) n( Q2 y& j8 s) N
下例将当前目录的内容写入当前服务器目录中名为 dir_out.txt 的文件中。 DECLARE @cmd sysname, @var sysname" i. \. ?6 X+ L
SET @var = 'dir/p'
4 K7 w7 g+ M: l m; D. V+ ]1 {- WSET @cmd = @var + ' > dir_out.txt'& Z$ E4 i* q# Y1 f( `
EXEC master..xp_cmdshell @cmd
3 q7 X/ ~, R/ K
/ O6 p/ b; t, r7 L* `4 z
' X$ O. n8 y' n W$ o8 U) p请参见
' r8 |+ c6 T, p3 G- @2 ?. V & }. J4 e% C, W" L9 z8 W s
sqlserver2000/tsqlref/ts_create_4hk5.htm">CREATE PROCEDURE
% r+ O2 K1 Z, d# hsqlserver2000/tsqlref/ts_ea-ez_05ro.htm">EXECUTE
3 J, M. o. H+ V( p0 [9 T创建安全帐户
3 r+ O- B) t. Z8 d7 m+ P* Usqlserver2000/tsqlref/ts_sp_00_519s.htm">系统存储过程(常规扩展过程)
) l6 G3 s1 L% r* u; R& k/ ]9 S, t& z* W2 |" C3 n/ [
, I) [+ d9 m# ]
|