<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>君子当盘的休憩小站</title>
  
  <subtitle>A Day Is One Day</subtitle>
  <link href="http://xiejing2014.github.io/atom.xml" rel="self"/>
  
  <link href="http://xiejing2014.github.io/"/>
  <updated>2018-06-01T10:16:22.000Z</updated>
  <id>http://xiejing2014.github.io/</id>
  
  <author>
    <name>君子当盘</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>陈浩-GDB（摘录）-备忘</title>
    <link href="http://xiejing2014.github.io/2018/06/01/%E9%99%88%E6%B5%A9-GDB%EF%BC%88%E6%91%98%E5%BD%95%EF%BC%89-%E5%A4%87%E5%BF%98/"/>
    <id>http://xiejing2014.github.io/2018/06/01/%E9%99%88%E6%B5%A9-GDB%EF%BC%88%E6%91%98%E5%BD%95%EF%BC%89-%E5%A4%87%E5%BF%98/</id>
    <published>2018-06-01T10:13:29.000Z</published>
    <updated>2018-06-01T10:16:22.000Z</updated>
    
    <content type="html"><![CDATA[<p><strong>援引陈浩写的GDB文章：</strong></p><p>1.用GDB调试程序（一）<br><a href="http://blog.csdn.net/haoel/article/details/2879">http://blog.csdn.net/haoel/article/details/2879</a></p><p>2.用GDB调试程序（二）<br><a href="http://blog.csdn.net/haoel/article/details/2880">http://blog.csdn.net/haoel/article/details/2880</a></p><p>3.用GDB调试程序（三）<br><a href="http://blog.csdn.net/haoel/article/details/2881">http://blog.csdn.net/haoel/article/details/2881</a></p><p>4.用GDB调试程序（四）<br><a href="http://blog.csdn.net/haoel/article/details/2882">http://blog.csdn.net/haoel/article/details/2882</a></p><p>5.用GDB调试程序（五）<br><a href="http://blog.csdn.net/haoel/article/details/2883">http://blog.csdn.net/haoel/article/details/2883</a></p><p>6.用GDB调试程序（六）<br><a href="http://blog.csdn.net/haoel/article/details/2884">http://blog.csdn.net/haoel/article/details/2884</a></p><p>7.用GDB调试程序（七）<br><a href="http://blog.csdn.net/haoel/article/details/2885">http://blog.csdn.net/haoel/article/details/2885</a></p><p>8.GDB中应该知道的几个调试方法<br><a href="https://coolshell.cn/articles/3643.html">https://coolshell.cn/articles/3643.html</a></p><p><strong>以下为学习正文，基于原文的学习汇总、更新。</strong></p><h1 id="GDB概述"><a href="#GDB概述" class="headerlink" title="GDB概述"></a>GDB概述</h1><p>GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许，各位比较喜欢那种图形界面方式的，像VC、BCB等IDE的调试，但如果你是在UNIX平台下做软件，你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长，尺有所短”就是这个道理。</p><p>一般来说，GDB主要帮忙你完成下面四个方面的功能：</p><pre><code>1、启动你的程序，可以按照你的自定义的要求随心所欲的运行程序。2、可让被调试的程序在你所指定的调置的断点处停住。（断点可以是条件表达式）3、当程序被停住时，可以检查此时你的程序中所发生的事。4、动态的改变你程序的执行环境。</code></pre><p>从上面看来，GDB和一般的调试工具没有什么两样，基本上也是完成这些功能，不过在细节上，你会发现GDB这个调试工具的强大，大家可能比较习惯了图形化的调试工具，但有时候，命令行的调试工具却有着图形化工具所不能完成的功能。让我们一一看来。</p><h1 id="一个调试示例"><a href="#一个调试示例" class="headerlink" title="一个调试示例"></a>一个调试示例</h1><p>源程序：tst.c</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">#include &lt;stdio.h&gt;</span><br><span class="line"></span><br><span class="line">int func(int n)</span><br><span class="line">&#123;</span><br><span class="line">    int sum=0,i;</span><br><span class="line">    for(i=0; i&lt;n; i++)&#123;</span><br><span class="line">            sum += i;</span><br><span class="line">    &#125;   </span><br><span class="line">    return sum;                                                                                                                                                                              </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">main()</span><br><span class="line">&#123;</span><br><span class="line">    int i;</span><br><span class="line">    long result = 0;</span><br><span class="line">    for(i=1; i&lt;=100; i++)&#123;</span><br><span class="line">        result += i;</span><br><span class="line">    &#125;   </span><br><span class="line">    </span><br><span class="line">    printf(&quot;result[1-100] = %d /n&quot;, result );</span><br><span class="line">    printf(&quot;result[1-250] = %d /n&quot;, func(250) );</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>编译：<br>gcc -g tst.c -o tst</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">简单地看下命令：</span><br><span class="line">[root@localhost gdb]# gdb tst   -- 开始调试</span><br><span class="line">GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7</span><br><span class="line">Copyright (C) 2013 Free Software Foundation, Inc.</span><br><span class="line">License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.  Type &quot;show copying&quot;</span><br><span class="line">and &quot;show warranty&quot; for details.</span><br><span class="line">This GDB was configured as &quot;x86_64-redhat-linux-gnu&quot;.</span><br><span class="line">For bug reporting instructions, please see:</span><br><span class="line">&lt;http://www.gnu.org/software/gdb/bugs/&gt;...</span><br><span class="line">Reading symbols from /root/gdb/tst...done.</span><br><span class="line"></span><br><span class="line">l,list，列出源代码信息。</span><br><span class="line">b 16 或者 b func,（break 16 或者 break func)，也就是在行或者函数处增加断点：</span><br><span class="line">    可以 info break 查看断点信息。</span><br><span class="line">    (gdb) b 16</span><br><span class="line">    Breakpoint 1 at 0x40056b: file tst.c, line 16.</span><br><span class="line">    (gdb) b func</span><br><span class="line">    Breakpoint 2 at 0x400534: file tst.c, line 5.</span><br><span class="line">    (gdb) info break</span><br><span class="line">    Num     Type           Disp Enb Address            What</span><br><span class="line">    1       breakpoint     keep y   0x000000000040056b in main at tst.c:16</span><br><span class="line">    2       breakpoint     keep y   0x0000000000400534 in func at tst.c:5</span><br><span class="line">r,run,运行程序。遇到断点的话，在断点处停下。</span><br><span class="line">    (gdb) r</span><br><span class="line">    The program being debugged has been started already.</span><br><span class="line">    Start it from the beginning? (y or n) y</span><br><span class="line">    Starting program: /root/gdb/tst </span><br><span class="line">    </span><br><span class="line">    Breakpoint 1, main () at tst.c:16</span><br><span class="line">    16          for(i=1; i&lt;=100; i++)&#123;</span><br><span class="line">n,next，单条语句执行。</span><br><span class="line">c,continue，继续运行程序。</span><br><span class="line">p,print,打印变量的值。</span><br><span class="line">bt,查看当前函数的堆栈信息。</span><br><span class="line">f,finish,退出函数。</span><br><span class="line">q,quit,退出gdb。</span><br><span class="line"></span><br><span class="line">执行结果不再赘列。</span><br></pre></td></tr></table></figure><h1 id="使用GDB"><a href="#使用GDB" class="headerlink" title="使用GDB"></a>使用GDB</h1><p>一般来说GDB主要调试的是C&#x2F;C++的程序。要调试C&#x2F;C++的程序，首先在编译时，我们必须要把调试信息加到可执行文件中。使用编译器（cc&#x2F;gcc&#x2F;g++）的 -g 参数可以做到这一点。如：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cc -g hello.c -o hello</span><br><span class="line">g++ -g hello.cpp -o hello</span><br></pre></td></tr></table></figure><p>如果没有-g，你将看不见程序的函数名、变量名，所代替的全是运行时的内存地址。当你用-g把调试信息加入之后，并成功编译目标代码以后，让我们来看看如何用gdb来调试他。</p><p>通过gdb -help可以查看gdb参数的使用说明。<br>查询可以知道，gdb的启用方式可以是以下几种：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">gdb [options] [executable-file [core-file or process-id]]</span><br><span class="line">gdb [options] --args executable-file [inferior-arguments ...]</span><br><span class="line">gdb [options] [--python|-P] script-file [script-arguments ...]</span><br><span class="line"></span><br><span class="line">即：gdb 执行程序/core文件/程序运行时pid</span><br><span class="line"></span><br><span class="line">常用参数：</span><br><span class="line">-symbols &lt;file&gt; / -s &lt;file&gt;</span><br><span class="line">从指定文件中读取符号表。</span><br><span class="line"></span><br><span class="line">-se file</span><br><span class="line">从指定文件中读取符号表信息，并把他用在可执行文件中。【mark】</span><br><span class="line"></span><br><span class="line">-core &lt;file&gt; / -c &lt;file&gt;</span><br><span class="line">调试时core dump的core文件。</span><br><span class="line"></span><br><span class="line">-directory &lt;directory&gt;</span><br><span class="line">-d &lt;directory&gt;</span><br><span class="line">加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。</span><br></pre></td></tr></table></figure><h1 id="GDB的命令概貌"><a href="#GDB的命令概貌" class="headerlink" title="GDB的命令概貌"></a>GDB的命令概貌</h1><p>启动gdb后，就你被带入gdb的调试环境中，就可以使用gdb的命令开始调试程序了，gdb的命令可以使用help命令来查看。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost gdb]# gdb</span><br><span class="line">GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7</span><br><span class="line">Copyright (C) 2013 Free Software Foundation, Inc.</span><br><span class="line">License GPLv3+: GNU GPL version 3 or later &lt;http://gnu.org/licenses/gpl.html&gt;</span><br><span class="line">This is free software: you are free to change and redistribute it.</span><br><span class="line">There is NO WARRANTY, to the extent permitted by law.  Type &quot;show copying&quot;</span><br><span class="line">and &quot;show warranty&quot; for details.</span><br><span class="line">This GDB was configured as &quot;x86_64-redhat-linux-gnu&quot;.</span><br><span class="line">For bug reporting instructions, please see:</span><br><span class="line">&lt;http://www.gnu.org/software/gdb/bugs/&gt;.</span><br><span class="line">(gdb) help</span><br><span class="line">List of classes of commands:</span><br><span class="line"></span><br><span class="line">aliases -- Aliases of other commands</span><br><span class="line">breakpoints -- Making program stop at certain points</span><br><span class="line">data -- Examining data</span><br><span class="line">files -- Specifying and examining files</span><br><span class="line">internals -- Maintenance commands</span><br><span class="line">obscure -- Obscure features</span><br><span class="line">running -- Running the program</span><br><span class="line">stack -- Examining the stack</span><br><span class="line">status -- Status inquiries</span><br><span class="line">support -- Support facilities</span><br><span class="line">tracepoints -- Tracing of program execution without stopping the program</span><br><span class="line">user-defined -- User-defined commands</span><br><span class="line"></span><br><span class="line">Type &quot;help&quot; followed by a class name for a list of commands in that class.</span><br><span class="line">Type &quot;help all&quot; for the list of all commands.</span><br><span class="line">Type &quot;help&quot; followed by command name for full documentation.</span><br><span class="line">Type &quot;apropos word&quot; to search for commands related to &quot;word&quot;.</span><br><span class="line">Command name abbreviations are allowed if unambiguous.</span><br><span class="line">(gdb) </span><br><span class="line"></span><br><span class="line">注意了，这里的help只是列出了gdb命令的种类。即 &lt;classes&gt;</span><br><span class="line">查看具体种类下的命令，继续help，如 help breakpoints。或者help &lt;commands&gt;。help b</span><br></pre></td></tr></table></figure><p>gdb中，输入命令时，可以不用打全命令，只用打命令的前几个字符就可以了，当然，命令的前几个字符应该要标志着一个唯一的命令，在Linux下，你可以敲击两次TAB键来补齐命令的全称，如果有重复的，那么gdb会把其例出来。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">## 省略、简写</span><br><span class="line">(gdb) b func</span><br><span class="line">Breakpoint 1 at 0x400534: file tst.c, line 5.</span><br><span class="line">(gdb) </span><br><span class="line"></span><br><span class="line">## tab两次</span><br><span class="line">(gdb) b</span><br><span class="line">backtrace    bookmark     break        break-range  bt           </span><br><span class="line">(gdb) </span><br><span class="line"></span><br><span class="line">## 对于函数名，也可以tab补全</span><br><span class="line">(gdb) b f</span><br><span class="line">frame_dummy  func         </span><br><span class="line">(gdb) </span><br></pre></td></tr></table></figure><h1 id="GDB中运行UNIX的shell程序"><a href="#GDB中运行UNIX的shell程序" class="headerlink" title="GDB中运行UNIX的shell程序"></a>GDB中运行UNIX的shell程序</h1><p>在gdb环境中，你可以执行UNIX的shell的命令，使用gdb的shell命令来完成：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">shell &lt;command string&gt;</span><br><span class="line">调用UNIX的shell来执行&lt;command string&gt;，环境变量SHELL中定义的UNIX的shell将会被用来执行&lt;command string&gt;，如果SHELL没有定义，那就使用UNIX的标准shell：/bin/sh。（在Windows中使用Command.com或cmd.exe）</span><br></pre></td></tr></table></figure><p>还有一个gdb命令是make：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make &lt;make-args&gt; </span><br><span class="line">可以在gdb中执行make命令来重新build自己的程序。这个命令等价于“shell make &lt;make-args&gt;”。</span><br></pre></td></tr></table></figure><p>操作：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(gdb) shell ls</span><br><span class="line">tst  tst.c</span><br><span class="line">(gdb) </span><br></pre></td></tr></table></figure><h1 id="在GDB中运行程序"><a href="#在GDB中运行程序" class="headerlink" title="在GDB中运行程序"></a>在GDB中运行程序</h1><p>当以gdb <program>方式启动gdb后，gdb会在PATH路径和当前目录中搜索<program>的源文件。如要确认gdb是否读到源文件，可使用l或list命令，看看gdb是否能列出源代码。</p><p>在gdb中，运行程序使用r或是run命令。程序的运行，你有可能需要设置下面四方面的事。</p><p>1、程序运行参数。<br>    set args 可指定运行时参数。（如：set args 10 20 30 40 50）<br>    show args 命令可以查看设置好的运行参数。</p><p>2、运行环境。<br>    path <dir> 可设定程序的运行路径。<br>    show paths 查看程序的运行路径。<br>    set environment varname [&#x3D;value] 设置环境变量。如：set env USER&#x3D;hchen<br>    show environment [varname] 查看环境变量。</p><p>3、工作目录。<br>    cd <dir> 相当于shell的cd命令。<br>    pwd 显示当前的所在目录。</p><p>4、程序的输入输出。<br>    info terminal 显示你程序用到的终端的模式。<br>    使用重定向控制程序输出。如：run &gt; outfile<br>    tty命令可以指写输入输出的终端设备。如：tty &#x2F;dev&#x2F;ttyb</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">(gdb) show args</span><br><span class="line">Argument list to give program being debugged when it is started is &quot;&quot;.</span><br><span class="line">(gdb) set args -d</span><br><span class="line">(gdb) show args</span><br><span class="line">Argument list to give program being debugged when it is started is &quot;-d&quot;.</span><br><span class="line">(gdb) r</span><br></pre></td></tr></table></figure><h1 id="调试已运行的程序"><a href="#调试已运行的程序" class="headerlink" title="调试已运行的程序"></a>调试已运行的程序</h1><p>两种方法：<br>1、在UNIX下用ps查看正在运行的程序的PID（进程ID），然后用gdb <program> PID格式挂接正在运行的程序。<br>2、先用gdb <program>关联上源代码，并进行gdb，在gdb中用attach命令来挂接进程的PID。并用detach来取消挂接的进程。</p><h1 id="暂停-x2F-恢复程序运行"><a href="#暂停-x2F-恢复程序运行" class="headerlink" title="暂停 &#x2F; 恢复程序运行"></a>暂停 &#x2F; 恢复程序运行</h1><p>调试程序中，暂停程序运行是必须的，GDB可以方便地暂停程序的运行。你可以设置程序的在哪行停住，在什么条件下停住，在收到什么信号时停往等等。以便于你查看运行时的变量，以及运行时的流程。</p><p>当进程被gdb停住时，你可以使用info program 来查看程序的是否在运行，进程号，被暂停的原因。</p><p>比如：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">(gdb) info program</span><br><span class="line">        Using the running image of child process 3566.</span><br><span class="line">Program stopped at 0x400534.</span><br><span class="line">It stopped at breakpoint 1.</span><br></pre></td></tr></table></figure><p>在gdb中，我们可以有以下几种暂停方式：断点（BreakPoint）、观察点（WatchPoint）、捕捉点（CatchPoint）、信号（Signals）、线程停止（Thread Stops）。如果要恢复程序运行，可以使用c或是continue命令。</p><p>一、设置断点（BreakPoint）</p><p>我们用break命令来设置断点。正面有几点设置断点的方法：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">break &lt;function&gt; </span><br><span class="line">    在进入指定函数时停住。C++中可以使用class::function或function(type,type)格式来指定函数名。</span><br><span class="line"></span><br><span class="line">break &lt;linenum&gt;</span><br><span class="line">    在指定行号停住。</span><br><span class="line"></span><br><span class="line">break +offset </span><br><span class="line">break -offset </span><br><span class="line">    在当前行号的前面或后面的offset行停住。offiset为自然数。</span><br><span class="line"></span><br><span class="line">break filename:linenum </span><br><span class="line">    在源文件filename的linenum行处停住。</span><br><span class="line"></span><br><span class="line">break filename:function </span><br><span class="line">    在源文件filename的function函数的入口处停住。</span><br><span class="line"></span><br><span class="line">break *address</span><br><span class="line">    在程序运行的内存地址处停住。</span><br><span class="line"></span><br><span class="line">break </span><br><span class="line">    break命令没有参数时，表示在下一条指令处停住。</span><br><span class="line"></span><br><span class="line">break ... if &lt;condition&gt;</span><br><span class="line">    ...可以是上述的参数，condition表示条件，在条件成立时停住。比如在循环境体中，可以设置break if i=100，表示当i为100时停住程序。</span><br></pre></td></tr></table></figure><p>查看断点时，可使用info命令，如下所示：（注：n表示断点号）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">info breakpoints [n] </span><br><span class="line">info break [n] </span><br></pre></td></tr></table></figure><p>二、设置观察点（WatchPoint）</p><p>观察点一般来观察某个表达式（变量也是一种表达式）的值是否有变化了，如果有变化，马上停住程序。我们有下面的几种方法来设置观察点：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">watch &lt;expr&gt;</span><br><span class="line">    为表达式（变量）expr设置一个观察点。一量表达式值有变化时，马上停住程序。</span><br><span class="line">        </span><br><span class="line">rwatch &lt;expr&gt;</span><br><span class="line">    当表达式（变量）expr被读时，停住程序。</span><br><span class="line">        </span><br><span class="line">awatch &lt;expr&gt;</span><br><span class="line">    当表达式（变量）的值被读或被写时，停住程序。</span><br><span class="line">    </span><br><span class="line">info watchpoints</span><br><span class="line">    列出当前所设置了的所有观察点。</span><br></pre></td></tr></table></figure><p>三、设置捕捉点（CatchPoint）</p><p>你可设置捕捉点来补捉程序运行时的一些事件。如：载入共享库（动态链接库）或是C++的异常。设置捕捉点的格式为：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">catch &lt;event&gt;</span><br><span class="line">    当event发生时，停住程序。event可以是下面的内容：</span><br><span class="line">    1、throw 一个C++抛出的异常。（throw为关键字）</span><br><span class="line">    2、catch 一个C++捕捉到的异常。（catch为关键字）</span><br><span class="line">    3、exec 调用系统调用exec时。（exec为关键字，目前此功能只在HP-UX下有用）</span><br><span class="line">    4、fork 调用系统调用fork时。（fork为关键字，目前此功能只在HP-UX下有用）</span><br><span class="line">    5、vfork 调用系统调用vfork时。（vfork为关键字，目前此功能只在HP-UX下有用）</span><br><span class="line">    6、load 或 load &lt;libname&gt;</span><br><span class="line">        载入共享库（动态链接库）时。（load为关键字，目前此功能只在HP-UX下有用）</span><br><span class="line">    7、unload 或 unload &lt;libname&gt;</span><br><span class="line">        卸载共享库（动态链接库）时。（unload为关键字，目前此功能只在HP-UX下有用）</span><br><span class="line"></span><br><span class="line">tcatch &lt;event&gt; </span><br><span class="line">    只设置一次捕捉点，当程序停住以后，应点被自动删除。</span><br></pre></td></tr></table></figure><p>四、维护停止点</p><p>上面说了如何设置程序的停止点，GDB中的停止点也就是上述的三类。在GDB中，如果你觉得已定义好的停止点没有用了，你可以使用delete、clear、disable、enable这几个命令来进行维护。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">clear</span><br><span class="line">    清除所有的已定义的停止点。</span><br><span class="line"></span><br><span class="line">clear &lt;function&gt;</span><br><span class="line">clear &lt;filename:function&gt;</span><br><span class="line">    清除所有设置在函数上的停止点。</span><br><span class="line"></span><br><span class="line">clear &lt;linenum&gt;</span><br><span class="line">clear &lt;filename:linenum&gt;</span><br><span class="line">    清除所有设置在指定行上的停止点。</span><br><span class="line"></span><br><span class="line">delete [breakpoints] [range...]</span><br><span class="line">    删除指定的断点，breakpoints为断点号。如果不指定断点号，则表示删除所有的断点。range 表示断点号的范围（如：3-7）。其简写命令为d。</span><br></pre></td></tr></table></figure><p>比删除更好的一种方法是disable停止点，disable了的停止点，GDB不会删除，当你还需要时，enable即可，就好像回收站一样。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">disable [breakpoints] [range...]</span><br><span class="line">    disable所指定的停止点，breakpoints为停止点号。如果什么都不指定，表示disable所有的停止点。简写命令是dis.</span><br><span class="line"></span><br><span class="line">enable [breakpoints] [range...]</span><br><span class="line">    enable所指定的停止点，breakpoints为停止点号。</span><br><span class="line"></span><br><span class="line">enable [breakpoints] once range...</span><br><span class="line">    enable所指定的停止点一次，当程序停止后，该停止点马上被GDB自动disable。</span><br><span class="line"></span><br><span class="line">enable [breakpoints] delete range...</span><br><span class="line">    enable所指定的停止点一次，当程序停止后，该停止点马上被GDB自动删除。</span><br></pre></td></tr></table></figure><p>比如执行：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">(gdb) info b</span><br><span class="line">Num     Type           Disp Enb Address            What</span><br><span class="line">1       breakpoint     keep y   0x0000000000400534 in func at tst.c:5</span><br><span class="line">        breakpoint already hit 1 time</span><br><span class="line">(gdb) disable 1</span><br><span class="line">(gdb) </span><br><span class="line">(gdb) info b</span><br><span class="line">Num     Type           Disp Enb Address            What</span><br><span class="line">1       breakpoint     keep n   0x0000000000400534 in func at tst.c:5</span><br><span class="line">        breakpoint already hit 1 time</span><br><span class="line">(gdb) enable 1</span><br><span class="line">(gdb) info b</span><br><span class="line">Num     Type           Disp Enb Address            What</span><br><span class="line">1       breakpoint     keep y   0x0000000000400534 in func at tst.c:5</span><br><span class="line">        breakpoint already hit 1 time</span><br><span class="line">(gdb) </span><br></pre></td></tr></table></figure><p>五、停止条件维护</p><p>前面在说到设置断点时，我们提到过可以设置一个条件，当条件成立时，程序自动停止，这是一个非常强大的功能，这里，我想专门说说这个条件的相关维护命令。一般来说，为断点设置一个条件，我们使用if关键词，后面跟其断点条件。并且，条件设置好后，我们可以用condition命令来修改断点的条件。（只有break和watch命令支持if，catch目前暂不支持if）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">condition &lt;bnum&gt; &lt;expression&gt;</span><br><span class="line">    修改断点号为bnum的停止条件为expression。</span><br><span class="line"></span><br><span class="line">condition &lt;bnum&gt;</span><br><span class="line">    清除断点号为bnum的停止条件。</span><br></pre></td></tr></table></figure><p>还有一个比较特殊的维护命令ignore，你可以指定程序运行时，忽略停止条件几次。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ignore &lt;bnum&gt; &lt;count&gt;</span><br><span class="line">    表示忽略断点号为bnum的停止条件count次。</span><br></pre></td></tr></table></figure><p>六、为停止点设定运行命令</p><p>我们可以使用GDB提供的command命令来设置停止点的运行命令。也就是说，当运行的程序在被停止住时，我们可以让其自动运行一些别的命令，这很有利行自动化调试。对基于GDB的自动化调试是一个强大的支持。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">commands [bnum]</span><br><span class="line">... command-list ...</span><br><span class="line">end</span><br></pre></td></tr></table></figure><p>为断点号bnum指写一个命令列表。当程序被该断点停住时，gdb会依次运行命令列表中的命令。<br>例如：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">break foo if x&gt;0</span><br><span class="line">commands</span><br><span class="line">printf &quot;x is %d/n&quot;,x</span><br><span class="line">continue</span><br><span class="line">end</span><br><span class="line">断点设置在函数foo中，断点条件是x&gt;0，如果程序被断住后，也就是，一旦x的值在foo函数中大于0，GDB会自动打印出x的值，并继续运行程序。</span><br></pre></td></tr></table></figure><p>如果你要清除断点上的命令序列，那么只要简单的执行一下commands命令，并直接在打个end就行了。</p><p>比如执行：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">(gdb) break 20 if i&gt;100</span><br><span class="line">Breakpoint 6 at 0x400587: file tst.c, line 20.</span><br><span class="line">(gdb) commands</span><br><span class="line">Type commands for breakpoint(s) 6, one per line.</span><br><span class="line">End with a line saying just &quot;end&quot;.</span><br><span class="line">&gt;printf &quot;i is %d\n&quot;,i</span><br><span class="line">&gt;continue</span><br><span class="line">&gt;end</span><br><span class="line">(gdb) r</span><br><span class="line">Starting program: /root/gdb/tst </span><br><span class="line"></span><br><span class="line">Breakpoint 6, main () at tst.c:20</span><br><span class="line">20          printf(&quot;result[1-100] = %d /n&quot;, result );</span><br><span class="line">i is 101</span><br><span class="line">result[1-100] = 5050 /nresult[1-250] = 31125 /n[Inferior 1 (process 7636) exited with code 030]</span><br><span class="line">(gdb) </span><br></pre></td></tr></table></figure><p>七、断点菜单</p><p>在C++中，可能会重复出现同一个名字的函数若干次（函数重载），在这种情况下，break <function>不能告诉GDB要停在哪个函数的入口。当然，你可以使用break &lt;function(type)&gt;也就是把函数的参数类型告诉GDB，以指定一个函数。否则的话，GDB会给你列出一个断点菜单供你选择你所需要的断点。你只要输入你菜单列表中的编号就可以了。如：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">(gdb) b String::after</span><br><span class="line">[0] cancel</span><br><span class="line">[1] all</span><br><span class="line">[2] file:String.cc; line number:867</span><br><span class="line">[3] file:String.cc; line number:860</span><br><span class="line">[4] file:String.cc; line number:875</span><br><span class="line">[5] file:String.cc; line number:853</span><br><span class="line">[6] file:String.cc; line number:846</span><br><span class="line">[7] file:String.cc; line number:735</span><br><span class="line">&gt; 2 4 6</span><br><span class="line">Breakpoint 1 at 0xb26c: file String.cc, line 867.</span><br><span class="line">Breakpoint 2 at 0xb344: file String.cc, line 875.</span><br><span class="line">Breakpoint 3 at 0xafcc: file String.cc, line 846.</span><br><span class="line">Multiple breakpoints were set.</span><br><span class="line">Use the &quot;delete&quot; command to delete unwanted</span><br><span class="line"> breakpoints.</span><br><span class="line">(gdb)</span><br><span class="line">#by xj 未试验</span><br></pre></td></tr></table></figure><p>可见，GDB列出了所有after的重载函数，你可以选一下列表编号就行了。0表示放弃设置断点，1表示所有函数都设置断点。</p><p>八、恢复程序运行和单步调试</p><p>当程序被停住了，你可以用continue命令恢复程序的运行直到程序结束，或下一个断点到来。也可以使用step或next命令单步跟踪程序。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">continue [ignore-count]</span><br><span class="line">c [ignore-count]</span><br><span class="line">fg [ignore-count]</span><br><span class="line">    恢复程序运行，直到程序结束，或是下一个断点到来。ignore-count表示忽略其后的断点次数。continue，c，fg三个命令都是一样的意思。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">step &lt;count&gt;</span><br><span class="line">    单步跟踪，如果有函数调用，他会进入该函数。进入函数的前提是，此函数被编译有debug信息。很像VC等工具中的step in。后面可以加count也可以不加，不加表示一条条地执行，加表示执行后面的count条指令，然后再停住。</span><br><span class="line"></span><br><span class="line">next &lt;count&gt;</span><br><span class="line">    同样单步跟踪，如果有函数调用，他不会进入该函数。很像VC等工具中的step over。后面可以加count也可以不加，不加表示一条条地执行，加表示执行后面的count条指令，然后再停住。</span><br><span class="line"></span><br><span class="line">set step-mode</span><br><span class="line">set step-mode on</span><br><span class="line">    打开step-mode模式，于是，在进行单步跟踪时，程序不会因为没有debug信息而不停住。这个参数有很利于查看机器码。</span><br><span class="line"></span><br><span class="line">set step-mod off</span><br><span class="line">    关闭step-mode模式。</span><br><span class="line"></span><br><span class="line">finish</span><br><span class="line">    运行程序，直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。</span><br><span class="line"></span><br><span class="line">until 或 u</span><br><span class="line">    当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。</span><br><span class="line"></span><br><span class="line">stepi 或 si</span><br><span class="line">nexti 或 ni</span><br><span class="line">    单步跟踪一条机器指令！一条程序代码有可能由数条机器指令完成，stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是“display/i $pc” ，当运行完这个命令后，单步跟踪会在打出程序代码的同时打出机器指令（也就是汇编代码）</span><br></pre></td></tr></table></figure><p>九、信号（Signals）</p><p>信号是一种软中断，是一种处理异步事件的方法。一般来说，操作系统都支持许多信号。尤其是UNIX，比较重要应用程序一般都会处理信号。UNIX定义了许多信号，比如SIGINT表示中断字符信号，也就是Ctrl+C的信号，SIGBUS表示硬件故障的信号；SIGCHLD表示子进程状态改变信号；SIGKILL表示终止程序运行的信号，等等。信号量编程是UNIX下非常重要的一种技术。</p><p>GDB有能力在你调试程序的时候处理任何一种信号，你可以告诉GDB需要处理哪一种信号。你可以要求GDB收到你所指定的信号时，马上停住正在运行的程序，以供你进行调试。你可以用GDB的handle命令来完成这一功能。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">handle &lt;signal&gt; &lt;keywords...&gt;</span><br><span class="line">    在GDB中定义一个信号处理。信号&lt;signal&gt;可以以SIG开头或不以SIG开头，可以用定义一个要处理信号的范围（如：SIGIO-SIGKILL，表示处理从SIGIO信号到SIGKILL的信号，其中包括SIGIO，SIGIOT，SIGKILL三个信号），也可以使用关键字all来标明要处理所有的信号。一旦被调试的程序接收到信号，运行程序马上会被GDB停住，以供调试。其&lt;keywords&gt;可以是以下几种关键字的一个或多个。</span><br><span class="line"></span><br><span class="line">    nostop</span><br><span class="line">        当被调试的程序收到信号时，GDB不会停住程序的运行，但会打出消息告诉你收到这种信号。</span><br><span class="line">    stop</span><br><span class="line">        当被调试的程序收到信号时，GDB会停住你的程序。</span><br><span class="line">    print</span><br><span class="line">        当被调试的程序收到信号时，GDB会显示出一条信息。</span><br><span class="line">    noprint</span><br><span class="line">        当被调试的程序收到信号时，GDB不会告诉你收到信号的信息。</span><br><span class="line">    pass</span><br><span class="line">    noignore</span><br><span class="line">        当被调试的程序收到信号时，GDB不处理信号。这表示，GDB会把这个信号交给被调试程序会处理。</span><br><span class="line">    nopass</span><br><span class="line">    ignore</span><br><span class="line">        当被调试的程序收到信号时，GDB不会让被调试程序来处理这个信号。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">info signals</span><br><span class="line">info handle</span><br><span class="line">    查看有哪些信号在被GDB检测中。</span><br></pre></td></tr></table></figure><p>十、线程（Thread Stops）</p><p>如果你程序是多线程的话，你可以定义你的断点是否在所有的线程上，或是在某个特定的线程。GDB很容易帮你完成这一工作。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">break &lt;linespec&gt; thread &lt;threadno&gt;</span><br><span class="line">break &lt;linespec&gt; thread &lt;threadno&gt; if ...</span><br><span class="line">    linespec指定了断点设置在的源程序的行号。threadno指定了线程的ID，注意，这个ID是GDB分配的，你可以通过“info threads”命令来查看正在运行程序中的线程信息。如果你不指定thread &lt;threadno&gt;则表示你的断点设在所有线程上面。你还可以为某线程指定断点条件。如：</span><br><span class="line"></span><br><span class="line">    (gdb) break frik.c:13 thread 28 if bartab &gt; lim</span><br><span class="line"></span><br><span class="line">当你的程序被GDB停住时，所有的运行线程都会被停住。这方便你你查看运行程序的总体情况。而在你恢复程序运行时，所有的线程也会被恢复运行。那怕是主进程在被单步调试时。</span><br></pre></td></tr></table></figure><h1 id="查看栈信息"><a href="#查看栈信息" class="headerlink" title="查看栈信息"></a>查看栈信息</h1><p>当程序被停住了，你需要做的第一件事就是查看程序是在哪里停住的。当你的程序调用了一个函数，函数的地址，函数参数，函数内的局部变量都会被压入“栈”（Stack）中。你可以用GDB命令来查看当前的栈中的信息。</p><p>下面是一些查看函数调用栈信息的GDB命令：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">    backtrace </span><br><span class="line">    bt </span><br><span class="line">        打印当前的函数调用栈的所有信息。如：</span><br><span class="line">        </span><br><span class="line">        (gdb) bt</span><br><span class="line">        #0  func (n=250) at tst.c:6</span><br><span class="line">        #1  0x08048524 in main (argc=1, argv=0xbffff674) at tst.c:30</span><br><span class="line">        #2  0x400409ed in __libc_start_main () from /lib/libc.so.6</span><br><span class="line">        </span><br><span class="line">        从上可以看出函数的调用栈信息：__libc_start_main --&gt; main() --&gt; func()</span><br><span class="line">        </span><br><span class="line">    </span><br><span class="line">    backtrace &lt;n&gt;</span><br><span class="line">    bt &lt;n&gt; </span><br><span class="line">        n是一个正整数，表示只打印栈顶上n层的栈信息。</span><br><span class="line"></span><br><span class="line">    backtrace &lt;-n&gt; </span><br><span class="line">    bt &lt;-n&gt; </span><br><span class="line">        -n表一个负整数，表示只打印栈底下n层的栈信息。</span><br><span class="line">```        </span><br><span class="line">如果你要查看某一层的信息，你需要在切换当前的栈，一般来说，程序停止时，最顶层的栈就是当前栈，如果你要查看栈下面层的详细信息，首先要做的是切换当前栈。</span><br></pre></td></tr></table></figure><pre><code>frame &lt;n&gt; f &lt;n&gt;     n是一个从0开始的整数，是栈中的层编号。比如：frame 0，表示栈顶，frame 1，表示栈的第二层。up &lt;n&gt;    表示向栈的上面移动n层，可以不打n，表示向上移动一层。     down &lt;n&gt;     表示向栈的下面移动n层，可以不打n，表示向下移动一层。    上面的命令，都会打印出移动到的栈层的信息。如果你不想让其打出信息。你可以使用这三个命令：        select-frame &lt;n&gt; 对应于 frame 命令。        up-silently &lt;n&gt; 对应于 up 命令。        down-silently &lt;n&gt; 对应于 down 命令。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">    </span><br><span class="line">查看当前栈层的信息，你可以用以下GDB命令：</span><br></pre></td></tr></table></figure><pre><code>frame 或 f     会打印出这些信息：栈的层编号，当前的函数名，函数参数值，函数所在文件及行号，函数执行到的语句。info frame info f     这个命令会打印出更为详细的当前栈层的信息，只不过，大多数都是运行时的内内地址。比如：函数地址，调用函数的地址，被调用函数的地址，目前的函数是由什么样的程序语言写成的、函数参数地址及值、局部变量的地址等等。如：        (gdb) info f        Stack level 0, frame at 0xbffff5d4:         eip = 0x804845d in func (tst.c:6); saved eip 0x8048524         called by frame at 0xbffff60c         source language c.         Arglist at 0xbffff5d4, args: n=250         Locals at 0xbffff5d4, Previous frame&#39;s sp is 0x0         Saved registers:          ebp at 0xbffff5d4, eip at 0xbffff5d8           info args    打印出当前函数的参数名及其值。  info locals    打印出当前函数中所有局部变量及其值。     info catch    打印出当前的函数中的异常处理信息。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># 查看源程序</span><br><span class="line"></span><br><span class="line">一、显示源代码</span><br><span class="line"></span><br><span class="line">    GDB 可以打印出所调试程序的源代码，当然，在程序编译时一定要加上-g的参数，把源程序信息编译到执行文件中。不然就看不到源程序了。当程序停下来以后，GDB会报告程序停在了那个文件的第几行上。你可以用list命令来打印程序的源代码。还是来看一看查看源代码的GDB命令吧。</span><br></pre></td></tr></table></figure><pre><code>list &lt;linenum&gt;    显示程序第linenum行的周围的源程序。list &lt;function&gt;     显示函数名为function的函数的源程序。    list     显示当前行后面的源程序。list -     显示当前行前面的源程序。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">一般是打印当前行的上5行和下5行，如果显示函数是是上2行下8行，默认是10行，当然，你也可以定制显示的范围，使用下面命令可以设置一次显示源程序的行数。</span><br></pre></td></tr></table></figure><pre><code>set listsize &lt;count&gt;    设置一次显示源代码的行数。    show listsize    查看当前listsize的设置。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">list命令还有下面的用法：</span><br></pre></td></tr></table></figure><pre><code>list &lt;first&gt;, &lt;last&gt;    显示从first行到last行之间的源代码。list , &lt;last&gt;    显示从当前行到last行之间的源代码。    list +    往后显示源代码。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">一般来说在list后面可以跟以下这们的参数：</span><br></pre></td></tr></table></figure><pre><code>&lt;linenum&gt;   行号。&lt;+offset&gt;   当前行号的正偏移量。&lt;-offset&gt;   当前行号的负偏移量。&lt;filename:linenum&gt;  哪个文件的哪一行。&lt;function&gt;  函数名。&lt;filename:function&gt; 哪个文件中的哪个函数。&lt;*address&gt;  程序运行时的语句在内存中的地址。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">二、搜索源代码</span><br><span class="line"></span><br><span class="line">不仅如此，GDB还提供了源代码搜索的命令：</span><br></pre></td></tr></table></figure><pre><code>forward-search &lt;regexp&gt; search &lt;regexp&gt;    向前面搜索。reverse-search &lt;regexp&gt;     全部搜索。    </code></pre><p>其中，<regexp>就是正则表达式，也主一个字符串的匹配模式，关于正则表达式，我就不在这里讲了，还请各位查看相关资料。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">三、指定源文件的路径</span><br><span class="line"></span><br><span class="line">某些时候，用-g编译过后的执行程序中只是包括了源文件的名字，没有路径名。GDB提供了可以让你指定源文件的路径的命令，以便GDB进行搜索。</span><br></pre></td></tr></table></figure><pre><code>directory &lt;dirname ... &gt;dir &lt;dirname ... &gt;    加一个源文件路径到当前路径的前面。如果你要指定多个路径，UNIX下你可以使用“:”，Windows下你可以使用“;”。directory     清除所有的自定义的源文件搜索路径信息。show directories     显示定义了的源文件搜索路径。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">四、源代码的内存</span><br><span class="line"></span><br><span class="line">你可以使用info line命令来查看源代码在内存中的地址。info line后面可以跟“行号”，“函数名”，“文件名:行号”，“文件名:函数名”，这个命令会打印出所指定的源码在运行时的内存地址，如：</span><br></pre></td></tr></table></figure><pre><code>    (gdb) info line tst.c:func    Line 5 of &quot;tst.c&quot; starts at address 0x8048456 &lt;func+6&gt; and ends at 0x804845d &lt;func+13&gt;.</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">还有一个命令（disassemble）你可以查看源程序的当前执行时的机器码，这个命令会把目前内存中的指令dump出来。如下面的示例表示查看函数func的汇编代码。</span><br></pre></td></tr></table></figure><pre><code>    (gdb) disassemble func    Dump of assembler code for function func:    0x8048450 &lt;func&gt;:       push   %ebp    0x8048451 &lt;func+1&gt;:     mov    %esp,%ebp    0x8048453 &lt;func+3&gt;:     sub    $0x18,%esp    0x8048456 &lt;func+6&gt;:     movl   $0x0,0xfffffffc(%ebp)    0x804845d &lt;func+13&gt;:    movl   $0x1,0xfffffff8(%ebp)    0x8048464 &lt;func+20&gt;:    mov    0xfffffff8(%ebp),%eax    0x8048467 &lt;func+23&gt;:    cmp    0x8(%ebp),%eax    0x804846a &lt;func+26&gt;:    jle    0x8048470 &lt;func+32&gt;    0x804846c &lt;func+28&gt;:    jmp    0x8048480 &lt;func+48&gt;    0x804846e &lt;func+30&gt;:    mov    %esi,%esi    0x8048470 &lt;func+32&gt;:    mov    0xfffffff8(%ebp),%eax    0x8048473 &lt;func+35&gt;:    add    %eax,0xfffffffc(%ebp)    0x8048476 &lt;func+38&gt;:    incl   0xfffffff8(%ebp)    0x8048479 &lt;func+41&gt;:    jmp    0x8048464 &lt;func+20&gt;    0x804847b &lt;func+43&gt;:    nop    0x804847c &lt;func+44&gt;:    lea    0x0(%esi,1),%esi    0x8048480 &lt;func+48&gt;:    mov    0xfffffffc(%ebp),%edx    0x8048483 &lt;func+51&gt;:    mov    %edx,%eax    0x8048485 &lt;func+53&gt;:    jmp    0x8048487 &lt;func+55&gt;    0x8048487 &lt;func+55&gt;:    mov    %ebp,%esp    0x8048489 &lt;func+57&gt;:    pop    %ebp    0x804848a &lt;func+58&gt;:    ret    End of assembler dump.</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"># 查看运行时数据</span><br><span class="line">    </span><br><span class="line">在你调试程序时，当程序被停住时，你可以使用print命令（简写命令为p），或是同义命令inspect来查看当前程序的运行数据。print命令的格式是：</span><br></pre></td></tr></table></figure><pre><code>print &lt;expr&gt;print /&lt;f&gt; &lt;expr&gt;    &lt;expr&gt;是表达式，是你所调试的程序的语言的表达式（GDB可以调试多种编程语言），&lt;f&gt;是输出的格式，比如，如果要把表达式按16进制的格式输出，那么就是/x。</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line">    </span><br><span class="line">一、表达式</span><br><span class="line"></span><br><span class="line">print和许多GDB的命令一样，可以接受一个表达式，GDB会根据当前的程序运行的数据来计算这个表达式，既然是表达式，那么就可以是当前程序运行中的const常量、变量、函数等内容。可惜的是GDB不能使用你在程序中所定义的宏。</span><br><span class="line">    </span><br><span class="line">表达式的语法应该是当前所调试的语言的语法，由于C/C++是一种大众型的语言，所以，本文中的例子都是关于C/C++的。（而关于用GDB调试其它语言的章节，我将在后面介绍）</span><br><span class="line">    </span><br><span class="line">在表达式中，有几种GDB所支持的操作符，它们可以用在任何一种语言中。</span><br><span class="line">    </span><br><span class="line">@</span><br><span class="line">    是一个和数组有关的操作符，在后面会有更详细的说明。</span><br><span class="line">        </span><br><span class="line">::</span><br><span class="line">    指定一个在文件或是一个函数中的变量。</span><br><span class="line">        </span><br><span class="line">&#123;&lt;type&gt;&#125; &lt;addr&gt;</span><br><span class="line">    表示一个指向内存地址&lt;addr&gt;的类型为type的一个对象。</span><br><span class="line">        </span><br><span class="line">        </span><br><span class="line">二、程序变量</span><br><span class="line"></span><br><span class="line">在GDB中，你可以随时查看以下三种变量的值：</span><br><span class="line">    1、全局变量（所有文件可见的）</span><br><span class="line">    2、静态全局变量（当前文件可见的）</span><br><span class="line">    3、局部变量（当前Scope可见的）</span><br><span class="line">        </span><br><span class="line">如果你的局部变量和全局变量发生冲突（也就是重名），一般情况下是局部变量会隐藏全局变量，也就是说，如果一个全局变量和一个函数中的局部变量同名时，如果当前停止点在函数中，用print显示出的变量的值会是函数中的局部变量的值。如果此时你想查看全局变量的值时，你可以使用“::”操作符：</span><br><span class="line">```    </span><br><span class="line">    file::variable</span><br><span class="line">    function::variable</span><br><span class="line">    可以通过这种形式指定你所想查看的变量，是哪个文件中的或是哪个函数中的。例如，查看文件f2.c中的全局变量x的值：</span><br><span class="line">    </span><br><span class="line">    gdb) p &#x27;f2.c&#x27;::x</span><br><span class="line">    </span><br><span class="line">    当然，“::”操作符会和C++中的发生冲突，GDB能自动识别“::” 是否C++的操作符，所以你不必担心在调试C++程序时会出现异常。</span><br><span class="line">```    </span><br><span class="line">另外，需要注意的是，如果你的程序编译时开启了优化选项，那么在用GDB调试被优化过的程序时，可能会发生某些变量不能访问，或是取值错误码的情况。这个是很正常的，因为优化程序会删改你的程序，整理你程序的语句顺序，剔除一些无意义的变量等，所以在GDB调试这种程序时，运行时的指令和你所编写指令就有不一样，也就会出现你所想象不到的结果。对付这种情况时，需要在编译程序时关闭编译优化。一般来说，几乎所有的编译器都支持编译优化的开关，例如，GNU的C/C++编译器GCC，你可以使用“-gstabs”选项来解决这个问题。关于编译器的参数，还请查看编译器的使用说明文档。</span><br><span class="line">   </span><br><span class="line">三、数组</span><br><span class="line"></span><br><span class="line">有时候，你需要查看一段连续的内存空间的值。比如数组的一段，或是动态分配的数据的大小。你可以使用GDB的“@”操作符，“@”的左边是第一个内存的地址的值，“@”的右边则你你想查看内存的长度。例如，你的程序中有这样的语句：</span><br><span class="line">     </span><br><span class="line">int *array = (int *) malloc (len * sizeof (int));</span><br><span class="line">        </span><br><span class="line">于是，在GDB调试过程中，你可以以如下命令显示出这个动态数组的取值：</span><br><span class="line"></span><br><span class="line">p *array@len</span><br><span class="line"></span><br><span class="line">@的左边是数组的首地址的值，也就是变量array所指向的内容，右边则是数据的长度，其保存在变量len中，其输出结果，大约是下面这个样子的：</span><br><span class="line">    </span><br><span class="line">(gdb) p *array@len</span><br><span class="line">$1 = &#123;2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40&#125;</span><br><span class="line"></span><br><span class="line">如果是静态数组的话，可以直接用print数组名，就可以显示数组中所有数据的内容了。</span><br><span class="line"></span><br><span class="line">    </span><br><span class="line">四、输出格式</span><br><span class="line"></span><br><span class="line">一般来说，GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如，你想输出一个整数的十六进制，或是二进制来查看这个整型变量的中的位的情况。要做到这样，你可以使用GDB的数据显示格式：</span><br></pre></td></tr></table></figure><pre><code>x  按十六进制格式显示变量。d  按十进制格式显示变量。u  按十六进制格式显示无符号整型。o  按八进制格式显示变量。t  按二进制格式显示变量。 a  按十六进制格式显示变量。c  按字符格式显示变量。f  按浮点数格式显示变量。    (gdb) p i    $21 = 101            (gdb) p/a i    $22 = 0x65        (gdb) p/c i    $23 = 101 &#39;e&#39;        (gdb) p/f i    $24 = 1.41531145e-43        (gdb) p/x i    $25 = 0x65        (gdb) p/t i    $26 = 1100101</code></pre><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">五、查看内存</span><br><span class="line"></span><br><span class="line">你可以使用examine命令（简写是x）来查看内存地址中的值。x命令的语法如下所示：</span><br><span class="line">```    </span><br><span class="line">    x/&lt;n/f/u&gt; &lt;addr&gt; </span><br><span class="line">    </span><br><span class="line">    n、f、u是可选的参数。</span><br><span class="line">    </span><br><span class="line">    n 是一个正整数，表示显示内存的长度，也就是说从当前地址向后显示几个地址的内容。</span><br><span class="line">    f 表示显示的格式，参见上面。如果地址所指的是字符串，那么格式可以是s，如果地十是指令地址，那么格式可以是i。</span><br><span class="line">    u 表示从当前地址往后请求的字节数，如果不指定的话，GDB默认是4个bytes。u参数可以用下面的字符来代替，b表示单字节，h表示双字节，w表示四字节，g表示八字节。当我们指定了字节长度后，GDB会从指内存定的内存地址开始，读写指定字节，并把其当作一个值取出来。</span><br><span class="line">    </span><br><span class="line">    &lt;addr&gt;表示一个内存地址。</span><br><span class="line"></span><br><span class="line">    n/f/u三个参数可以一起使用。例如：</span><br><span class="line">    </span><br><span class="line">    命令：x/3uh 0x54320 表示，从内存地址0x54320读取内容，h表示以双字节为一个单位，3表示三个单位，u表示按十六进制显示。</span><br><span class="line">```    </span><br><span class="line">    </span><br><span class="line">六、自动显示</span><br><span class="line"></span><br><span class="line">你可以设置一些自动显示的变量，当程序停住时，或是在你单步跟踪时，这些变量会自动显示。相关的GDB命令是display。</span><br><span class="line">```    </span><br><span class="line">    display &lt;expr&gt; </span><br><span class="line">    display/&lt;fmt&gt; &lt;expr&gt; </span><br><span class="line">    display/&lt;fmt&gt; &lt;addr&gt;</span><br><span class="line">    </span><br><span class="line">    expr是一个表达式，fmt表示显示的格式，addr表示内存地址，当你用display设定好了一个或多个表达式后，只要你的程序被停下来，GDB会自动显示你所设置的这些表达式的值。</span><br><span class="line">    </span><br><span class="line">    格式i和s同样被display支持，一个非常有用的命令是：</span><br><span class="line">    </span><br><span class="line">        display/i $pc</span><br><span class="line">    </span><br><span class="line">    $pc是GDB的环境变量，表示着指令的地址，/i则表示输出格式为机器指令码，也就是汇编。于是当程序停下后，就会出现源代码和机器指令码相对应的情形，这是一个很有意思的功能。</span><br><span class="line">    </span><br><span class="line">    下面是一些和display相关的GDB命令：</span><br><span class="line">    </span><br><span class="line">    undisplay &lt;dnums...&gt;</span><br><span class="line">    delete display &lt;dnums...&gt;</span><br><span class="line">    删除自动显示，dnums意为所设置好了的自动显式的编号。如果要同时删除几个，编号可以用空格分隔，如果要删除一个范围内的编号，可以用减号表示（如：2-5）</span><br><span class="line">    </span><br><span class="line">    disable display &lt;dnums...&gt;</span><br><span class="line">    enable display &lt;dnums...&gt;</span><br><span class="line">    disable和enalbe不删除自动显示的设置，而只是让其失效和恢复。</span><br><span class="line">    </span><br><span class="line">    info display</span><br><span class="line">    查看display设置的自动显示的信息。GDB会打出一张表格，向你报告当然调试中设置了多少个自动显示设置，其中包括，设置的编号，表达式，是否enable。</span><br></pre></td></tr></table></figure><p>七、设置显示选项</p><p>GDB中关于显示的选项比较多，这里我只例举大多数常用的选项。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br></pre></td><td class="code"><pre><span class="line">    set print address </span><br><span class="line">    set print address on </span><br><span class="line">        打开地址输出，当程序显示函数信息时，GDB会显出函数的参数地址。系统默认为打开的，如：</span><br><span class="line">        </span><br><span class="line">        (gdb) f</span><br><span class="line">        #0  set_quotes (lq=0x34c78 &quot;&lt;&lt;&quot;, rq=0x34c88 &quot;&gt;&gt;&quot;)</span><br><span class="line">            at input.c:530</span><br><span class="line">        530         if (lquote != def_lquote)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    set print address off </span><br><span class="line">        关闭函数的参数地址显示，如：</span><br><span class="line">        </span><br><span class="line">        (gdb) set print addr off</span><br><span class="line">        (gdb) f</span><br><span class="line">        #0  set_quotes (lq=&quot;&lt;&lt;&quot;, rq=&quot;&gt;&gt;&quot;) at input.c:530</span><br><span class="line">        530         if (lquote != def_lquote)</span><br><span class="line"></span><br><span class="line">    show print address </span><br><span class="line">        查看当前地址显示选项是否打开。</span><br><span class="line">        </span><br><span class="line">    set print array </span><br><span class="line">    set print array on </span><br><span class="line">        打开数组显示，打开后当数组显示时，每个元素占一行，如果不打开的话，每个元素则以逗号分隔。这个选项默认是关闭的。与之相关的两个命令如下，我就不再多说了。</span><br><span class="line">        </span><br><span class="line">    set print array off </span><br><span class="line">    show print array</span><br><span class="line"></span><br><span class="line">    set print elements &lt;number-of-elements&gt;</span><br><span class="line">        这个选项主要是设置数组的，如果你的数组太大了，那么就可以指定一个&lt;number-of-elements&gt;来指定数据显示的最大长度，当到达这个长度时，GDB就不再往下显示了。如果设置为0，则表示不限制。</span><br><span class="line">        </span><br><span class="line">    show print elements </span><br><span class="line">        查看print elements的选项信息。</span><br><span class="line">        </span><br><span class="line">    set print null-stop &lt;on/off&gt;</span><br><span class="line">        如果打开了这个选项，那么当显示字符串时，遇到结束符则停止显示。这个选项默认为off。</span><br><span class="line">        </span><br><span class="line">    set print pretty on </span><br><span class="line">        如果打开printf pretty这个选项，那么当GDB显示结构体时会比较漂亮。如：</span><br><span class="line"></span><br><span class="line">            $1 = &#123;</span><br><span class="line">              next = 0x0,</span><br><span class="line">              flags = &#123;</span><br><span class="line">                sweet = 1,</span><br><span class="line">                sour = 1</span><br><span class="line">              &#125;,</span><br><span class="line">              meat = 0x54 &quot;Pork&quot;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">    set print pretty off</span><br><span class="line">        关闭printf pretty这个选项，GDB显示结构体时会如下显示：</span><br><span class="line">        </span><br><span class="line">            $1 = &#123;next = 0x0, flags = &#123;sweet = 1, sour = 1&#125;, meat = 0x54 &quot;Pork&quot;&#125;</span><br><span class="line">            </span><br><span class="line">    show print pretty </span><br><span class="line">        查看GDB是如何显示结构体的。</span><br><span class="line">        </span><br><span class="line">    </span><br><span class="line">    set print sevenbit-strings &lt;on/off&gt;</span><br><span class="line">        设置字符显示，是否按“/nnn”的格式显示，如果打开，则字符串或字符数据按/nnn显示，如“/065”。</span><br><span class="line">    </span><br><span class="line">    show print sevenbit-strings</span><br><span class="line">        查看字符显示开关是否打开。 </span><br><span class="line">        </span><br><span class="line">    set print union &lt;on/off&gt;</span><br><span class="line">        设置显示结构体时，是否显式其内的联合体数据。例如有以下数据结构：</span><br><span class="line">        </span><br><span class="line">        typedef enum &#123;Tree, Bug&#125; Species;</span><br><span class="line">        typedef enum &#123;Big_tree, Acorn, Seedling&#125; Tree_forms;</span><br><span class="line">        typedef enum &#123;Caterpillar, Cocoon, Butterfly&#125;</span><br><span class="line">                      Bug_forms;</span><br><span class="line">        </span><br><span class="line">        struct thing &#123;</span><br><span class="line">          Species it;</span><br><span class="line">          union &#123;</span><br><span class="line">            Tree_forms tree;</span><br><span class="line">            Bug_forms bug;</span><br><span class="line">          &#125; form;</span><br><span class="line">        &#125;;</span><br><span class="line">        </span><br><span class="line">        struct thing foo = &#123;Tree, &#123;Acorn&#125;&#125;;</span><br><span class="line"></span><br><span class="line">        当打开这个开关时，执行 p foo 命令后，会如下显示：</span><br><span class="line">            $1 = &#123;it = Tree, form = &#123;tree = Acorn, bug = Cocoon&#125;&#125;</span><br><span class="line">        </span><br><span class="line">        当关闭这个开关时，执行 p foo 命令后，会如下显示：</span><br><span class="line">            $1 = &#123;it = Tree, form = &#123;...&#125;&#125;</span><br><span class="line"></span><br><span class="line">    show print union</span><br><span class="line">        查看联合体数据的显示方式</span><br><span class="line">        </span><br><span class="line">    set print object &lt;on/off&gt;</span><br><span class="line">        在C++中，如果一个对象指针指向其派生类，如果打开这个选项，GDB会自动按照虚方法调用的规则显示输出，如果关闭这个选项的话，GDB就不管虚函数表了。这个选项默认是off。</span><br><span class="line">    </span><br><span class="line">    show print object</span><br><span class="line">        查看对象选项的设置。</span><br><span class="line">        </span><br><span class="line">    set print static-members &lt;on/off&gt;</span><br><span class="line">        这个选项表示，当显示一个C++对象中的内容是，是否显示其中的静态数据成员。默认是on。</span><br><span class="line">    </span><br><span class="line">    show print static-members</span><br><span class="line">        查看静态数据成员选项设置。</span><br><span class="line">        </span><br><span class="line">    set print vtbl &lt;on/off&gt;</span><br><span class="line">        当此选项打开时，GDB将用比较规整的格式来显示虚函数表时。其默认是关闭的。</span><br><span class="line">        </span><br><span class="line">    show print vtbl</span><br><span class="line">        查看虚函数显示格式的选项。</span><br><span class="line">```        </span><br><span class="line">        </span><br><span class="line">八、历史记录</span><br><span class="line"></span><br><span class="line">当你用GDB的print查看程序运行时的数据时，你每一个print都会被GDB记录下来。GDB会以```$1, $2, $3``` .....这样的方式为你每一个print命令编上号。于是，你可以使用这个编号访问以前的表达式，如```$1```。这个功能所带来的好处是，如果你先前输入了一个比较长的表达式，如果你还想查看这个表达式的值，你可以使用历史记录来访问，省去了重复输入。</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">九、GDB环境变量</span><br><span class="line"></span><br><span class="line">你可以在GDB的调试环境中定义自己的变量，用来保存一些调试程序中的运行数据。要定义一个GDB的变量很简单只需。使用GDB的set命令。GDB的环境变量和UNIX一样，也是以$起头。如：</span><br><span class="line">```    </span><br><span class="line">    set $foo = *object_ptr</span><br><span class="line">    </span><br><span class="line">    使用环境变量时，GDB会在你第一次使用时创建这个变量，而在以后的使用中，则直接对其賦值。环境变量没有类型，你可以给环境变量定义任一的类型。包括结构体和数组。</span><br><span class="line">    </span><br><span class="line">    show convenience </span><br><span class="line">        该命令查看当前所设置的所有的环境变量。</span><br><span class="line">        </span><br><span class="line">    这是一个比较强大的功能，环境变量和程序变量的交互使用，将使得程序调试更为灵活便捷。例如：</span><br><span class="line">    </span><br><span class="line">        set $i = 0</span><br><span class="line">        print bar[$i++]-&gt;contents</span><br><span class="line">    </span><br><span class="line">    于是，当你就不必，print bar[0]-&gt;contents, print bar[1]-&gt;contents地输入命令了。输入这样的命令后，只用敲回车，重复执行上一条语句，环境变量会自动累加，从而完成逐个输出的功能。</span><br><span class="line">```    </span><br><span class="line">    </span><br><span class="line">十、查看寄存器</span><br><span class="line"></span><br><span class="line">要查看寄存器的值，很简单，可以使用如下命令：</span><br><span class="line">```    </span><br><span class="line">    info registers </span><br><span class="line">        查看寄存器的情况。（除了浮点寄存器）</span><br><span class="line">    </span><br><span class="line">    info all-registers</span><br><span class="line">        查看所有寄存器的情况。（包括浮点寄存器）</span><br><span class="line">    </span><br><span class="line">    info registers &lt;regname ...&gt;</span><br><span class="line">        查看所指定的寄存器的情况。</span><br><span class="line">```        </span><br><span class="line">寄存器中放置了程序运行时的数据，比如程序当前运行的指令地址（ip），程序的当前堆栈地址（sp）等等。你同样可以使用print命令来访问寄存器的情况，只需要在寄存器名字前加一个$符号就可以了。如：p $eip。</span><br><span class="line"></span><br><span class="line"># 改变程序的执行</span><br><span class="line"></span><br><span class="line">一旦使用GDB挂上被调试程序，当程序运行起来后，你可以根据自己的调试思路来动态地在GDB中更改当前被调试程序的运行线路或是其变量的值，这个强大的功能能够让你更好的调试你的程序，比如，你可以在程序的一次运行中走遍程序的所有分支。</span><br><span class="line">    </span><br><span class="line">    </span><br><span class="line">一、修改变量值</span><br><span class="line"></span><br><span class="line">修改被调试程序运行时的变量值，在GDB中很容易实现，使用GDB的print命令即可完成。如：</span><br><span class="line">```    </span><br><span class="line">        (gdb) print x=4</span><br><span class="line">    </span><br><span class="line">    x=4这个表达式是C/C++的语法，意为把变量x的值修改为4，如果你当前调试的语言是Pascal，那么你可以使用Pascal的语法：x:=4。</span><br><span class="line">    </span><br><span class="line">    在某些时候，很有可能你的变量和GDB中的参数冲突，如：</span><br><span class="line">    </span><br><span class="line">        (gdb) whatis width</span><br><span class="line">        type = double</span><br><span class="line">        (gdb) p width</span><br><span class="line">        $4 = 13</span><br><span class="line">        (gdb) set width=47</span><br><span class="line">        Invalid syntax in expression.</span><br><span class="line"></span><br><span class="line">    因为，set width是GDB的命令，所以，出现了“Invalid syntax in expression”的设置错误，此时，你可以使用set var命令来告诉GDB，width不是你GDB的参数，而是程序的变量名，如：</span><br><span class="line">    </span><br><span class="line">        (gdb) set var width=47</span><br><span class="line">        </span><br><span class="line">    另外，还可能有些情况，GDB并不报告这种错误，所以保险起见，在你改变程序变量取值时，最好都使用set var格式的GDB命令。</span><br><span class="line">```   </span><br><span class="line"></span><br><span class="line">二、跳转执行</span><br><span class="line"></span><br><span class="line">一般来说，被调试程序会按照程序代码的运行顺序依次执行。GDB提供了乱序执行的功能，也就是说，GDB可以修改程序的执行顺序，可以让程序执行随意跳跃。这个功能可以由GDB的jump命令来完：</span><br><span class="line">```    </span><br><span class="line">    jump &lt;linespec&gt;</span><br><span class="line">    指定下一条语句的运行点。&lt;linespce&gt;可以是文件的行号，可以是file:line格式，可以是+num这种偏移量格式。表式着下一条运行语句从哪里开始。</span><br><span class="line">    </span><br><span class="line">    jump &lt;address&gt;</span><br><span class="line">    这里的&lt;address&gt;是代码行的内存地址。</span><br><span class="line">    </span><br><span class="line">    注意，jump命令不会改变当前的程序栈中的内容，所以，当你从一个函数跳到另一个函数时，当函数运行完返回时进行弹栈操作时必然会发生错误，可能结果还是非常奇怪的，甚至于产生程序Core Dump。所以最好是同一个函数中进行跳转。</span><br><span class="line">    </span><br><span class="line">    熟悉汇编的人都知道，程序运行时，有一个寄存器用于保存当前代码所在的内存地址。所以，jump命令也就是改变了这个寄存器中的值。于是，你可以使用“set $pc”来更改跳转执行的地址。如：</span><br><span class="line">    </span><br><span class="line">    set $pc = 0x485</span><br></pre></td></tr></table></figure><p>三、产生信号量</p><p>使用singal命令，可以产生一个信号量给被调试的程序。如：中断信号Ctrl+C。这非常方便于程序的调试，可以在程序运行的任意位置设置断点，并在该断点用GDB产生一个信号量，这种精确地在某处产生信号非常有利程序的调试。</p><p>语法是：signal <singal>，UNIX的系统信号量通常从1到15。所以<singal>取值也在这个范围。</p><p>single命令和shell的kill命令不同，系统的kill命令发信号给被调试程序时，是由GDB截获的，而single命令所发出一信号则是直接发给被调试程序的。</p><p>四、强制函数返回</p><p>如果你的调试断点在某个函数中，并还有语句没有执行完。你可以使用return命令强制函数忽略还没有执行的语句并返回。</p><p>return<br>return <expression></p><p>使用return命令取消当前函数的执行，并立即返回，如果指定了<expression>，那么该表达式的值会被认作函数的返回值。</p><p>五、强制调用函数</p><p>call <expr><br>表达式中可以一是函数，以此达到强制调用函数的目的。并显示函数的返回值，如果函数返回值是void，那么就不显示。</p><p>另一个相似的命令也可以完成这一功能——print，print后面可以跟表达式，所以也可以用他来调用函数，print和call的不同是，如果函数返回void，call则不显示，print则显示函数返回值，并把该值存入历史数据中。</p><h1 id="在不同语言中使用GDB"><a href="#在不同语言中使用GDB" class="headerlink" title="在不同语言中使用GDB"></a>在不同语言中使用GDB</h1><p>GDB支持下列语言：C, C++, Fortran, PASCAL, Java, Chill, assembly, 和 Modula-2。一般说来，GDB会根据你所调试的程序来确定当然的调试语言，比如：发现文件名后缀为“.c”的，GDB会认为是C程序。文件名后缀为“.C, .cc, .cp, .cpp, .cxx, .c++”的，GDB会认为是C++程序。而后缀是“.f, .F”的，GDB会认为是Fortran程序，还有，后缀为如果是“.s, .S”的会认为是汇编语言。</p><p>也就是说，GDB会根据你所调试的程序的语言，来设置自己的语言环境，并让GDB的命令跟着语言环境的改变而改变。比如一些GDB命令需要用到表达式或变量时，这些表达式或变量的语法，完全是根据当前的语言环境而改变的。例如C&#x2F;C++中对指针的语法是*p，而在Modula-2中则是p^。并且，如果你当前的程序是由几种不同语言一同编译成的，那到在调试过程中，GDB也能根据不同的语言自动地切换语言环境。这种跟着语言环境而改变的功能，真是体贴开发人员的一种设计。</p><p>下面是几个相关于GDB语言环境的命令：</p><pre><code>    show language         查看当前的语言环境。如果GDB不能识为你所调试的编程语言，那么，C语言被认为是默认的环境。            info frame        查看当前函数的程序语言。            info source        查看当前文件的程序语言。</code></pre><p>如果GDB没有检测出当前的程序语言，那么你也可以手动设置当前的程序语言。使用set language命令即可做到。</p><p>当set language命令后什么也不跟的话，你可以查看GDB所支持的语言种类：</p><pre><code>        (gdb) set language        The currently understood settings are:                local or auto    Automatic setting based on source file        c                Use the C language        c++              Use the C++ language        asm              Use the Asm language        chill            Use the Chill language        fortran          Use the Fortran language        java             Use the Java language        modula-2         Use the Modula-2 language        pascal           Use the Pascal language        scheme           Use the Scheme language            于是你可以在set language后跟上被列出来的程序语言名，来设置当前的语言环境。</code></pre><h1 id="陈浩-后记"><a href="#陈浩-后记" class="headerlink" title="陈浩-后记"></a>陈浩-后记</h1><p>GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于，其可以形成执行序列，形成脚本。UNIX下的软件全是命令行的，这给程序开发提代供了极大的便利，命令行软件的优势在于，它们可以非常容易的集成在一起，使用几个简单的已有工具的命令，就可以做出一个非常强大的功能。</p><p>于是UNIX下的软件比Windows下的软件更能有机地结合，各自发挥各自的长处，组合成更为强劲的功能。而Windows下的图形软件基本上是各自为营，互相不能调用，很不利于各种软件的相互集成。在这里并不是要和Windows做个什么比较，所谓“寸有所长，尺有所短”，图形化工具还是有不如命令行的地方。（看到这句话时，希望各位千万再也不要认为我就是“鄙视图形界面”，和我抬杠了 ）</p><p>我是根据版本为5.1.1的GDB所写的这篇文章，所以可能有些功能已被修改，或是又有更为强劲的功能。而且，我写得非常仓促，写得比较简略，并且，其中我已经看到有许多错别字了（我用五笔，所以错字让你看不懂），所以，我在这里对我文中的差错表示万分的歉意。</p><p>文中所罗列的GDB的功能时，我只是罗列了一些带用的GDB的命令和使用方法，其实，我这里只讲述的功能大约只占GDB所有功能的60%吧，详细的文档，还是请查看GDB的帮助和使用手册吧，或许，过段时间，如果我有空，我再写一篇GDB的高级使用。</p><p>我个人非常喜欢GDB的自动调试的功能，这个功能真的很强大，试想，我在UNIX下写个脚本，让脚本自动编译我的程序，被自动调试，并把结果报告出来，调试成功，自动checkin源码库。一个命令，编译带着调试带着checkin，多爽啊。只是GDB对自动化调试目前支持还不是很成熟，只能实现半自动化，真心期望着GDB的自动化调试功能的成熟。</p><p>如果各位对GDB或是别的技术问题有兴趣的话，欢迎和我讨论交流。本人目前主要在UNIX下做产品软件的开发，所以，对UNIX下的软件开发比较熟悉，当然，不单单是技术，对软件工程实施，软件设计，系统分析，项目管理我也略有心得。欢迎大家找我交流，（QQ是：753640，MSN是：<a href="mailto:&#104;&#x61;&#111;&#101;&#x6c;&#x40;&#104;&#x6f;&#116;&#109;&#97;&#x69;&#108;&#46;&#x63;&#111;&#109;">&#104;&#x61;&#111;&#101;&#x6c;&#x40;&#104;&#x6f;&#116;&#109;&#97;&#x69;&#108;&#46;&#x63;&#111;&#109;</a>）</p><h1 id="本人-后记"><a href="#本人-后记" class="headerlink" title="本人-后记"></a>本人-后记</h1><p><strong>关于GDB，个人常用的命令并不多，目前来说，视工作情况适当拓展gdb的使用。</strong><br><strong>方便调试&amp;代码阅读的工具而已，加断点，合适的地方获取到想要的信息才是目的</strong></p><p><strong>本文摘录，用于备忘，同时敬仰一下大神</strong></p><p>“GDB中应该知道的几个调试方法”这篇文章倒是木有添加什么新内容，关于macro调试宏倒是又新提及了一些：<br>摘录如下：</p><p>在GDB下，我们无法print宏定义，因为宏是预编译的。但是我们还是有办法来调试宏，这个需要GCC的配合。</p><p>在GCC编译程序的时候，加上-ggdb3参数，这样，你就可以调试宏了。</p><p>另外，你可以使用下述的GDB的宏调试命令 来查看相关的宏。</p><p>info macro – 你可以查看这个宏在哪些文件里被引用了，以及宏定义是什么样的。<br>macro – 你可以查看宏展开的样子。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;strong&gt;援引陈浩写的GDB文章：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1.用GDB调试程序（一）&lt;br&gt;&lt;a href=&quot;http://blog.csdn.net/haoel/article/details/2879&quot;&gt;http://blog.csdn.net/haoe</summary>
      
    
    
    
    <category term="其他" scheme="http://xiejing2014.github.io/categories/%E5%85%B6%E4%BB%96/"/>
    
    
    <category term="gdb" scheme="http://xiejing2014.github.io/tags/gdb/"/>
    
  </entry>
  
  <entry>
    <title>informix历史（转帖-2）</title>
    <link href="http://xiejing2014.github.io/2018/06/01/informix%E5%8E%86%E5%8F%B2%EF%BC%88%E8%BD%AC%E5%B8%96-2%EF%BC%89/"/>
    <id>http://xiejing2014.github.io/2018/06/01/informix%E5%8E%86%E5%8F%B2%EF%BC%88%E8%BD%AC%E5%B8%96-2%EF%BC%89/</id>
    <published>2018-06-01T05:48:10.000Z</published>
    <updated>2018-06-01T06:02:46.000Z</updated>
    
    <content type="html"><![CDATA[<p>Informix在1980年成立，目的是为Unix等开放操作系统提供专业的关系型数据库产品。公司的名称Informix便是取自Information和Unix的结合。</p><p>Informix第一个真正支持SQL语言的关系数据库产品是InformixSE（StandardEngine）。InformixSE的特点是简单、轻便、适应性强。它的装机量非常之大，尤其是在当时的微机Unix环境下，成为主要的数据库产品。它也是第一个被移植到Linux上的商业数据库产品。</p><p>在90年代初，联机事务处理成为关系数据库越来越主要的应用，同时，Client&#x2F;Server结构日渐兴起。为了满足基于Client&#x2F;Server环境下联机事务处理的需要，Informix在其数据库产品中引入了Client&#x2F;Server的概念，将应用对数据库的请求与数据库对请求的处理分割开来，推出了Informix-OnLine，OnLine的一个特点是数据的管理的重大改变，即数据表不再是单个的文件，而是数据库空间和逻辑设备。逻辑设备不仅可以建立在文件系统之上，还可以是硬盘的分区和裸设备。由此提高了数据的安全性。</p><p>1993年，为了克服多进程系统性能的局限性，Informix使用多线程机制重新改写数据库核心，次年初，Informix推出了采用被称为”动态可伸缩结构”（DSA）的InformixDynamicServer。除了应用线程机制以外，Informix在数据库核心中引入了虚处理器的概念，每个虚处理器就是一个Informix数据库服务器进程。在DynamicServer中，多条线程可以在虚处理器缓冲池中并行执行，而每个虚处理机又被实际的多处理机调度执行。更重要的是：为了执行高效性和多功能的调谐，Informix将虚处理器根据不同的处理任务进行了分类。每一类被优化以完成一种特定的功能。</p><p>到90年代后期，随着Internet的兴起，电子文档、图片、视频、空间信息、Internet&#x2F;Web等应用潮水般涌入IT行业，而关系数据库所管理的数据类型仍停留在数字、字符串、日期等六七十年代的水平上，其处理能力便显得力不从心了。1992年，著名的数据库学者、Ingres的创始人加州大学伯克利分校的MichaelStonebraker教授提出对象关系数据库模型，从而找到了一条解决问题的有效途径。</p><p>1995年，Stonebraker及其研发组织的加入了Informix，使之在数据库发展方向上有了一个新的突破：1996年Informix推出了通用数据选件（Universal Data Option）。这是一个对象关系模型的数据库服务器；它与其他厂商中间件的解决方案不同，从关系数据库服务器内部的各个环节对数据库进行面向对象的扩充；将关系数据库的各种机制抽象化、通用化。UniversalDataOption采用了DynamicServer的所有底层技术，如DSA结构和并行处理，同时允许用户在数据库中建立复杂的数据类型及用户自定义的数据类型，同时可对这些数据类型定义各种操作和运算以实现对象的封装。在定义操作和运算时可以采用数据库过程语言、C语言，它们经注册后成为服务器的一部分。</p><p>1999年，Informix进一步将Universal Data Option进行了优化，为用户自定义数据类型和操作过程提供了完整的工具环境。同时在传统事务处理的性能超过了以往的Dynamic Server。新的数据库核心便被命名为IDS.2000。它的目标定位于下世纪基于Internet的复杂数据库应用。</p><p>事实上，Internet的普及从Web开始。Web应用以简便和图文并茂见长。但充斥整个系统的HTML文件又将我们不知不觉地带回了文件系统的时代。采用数据库管理Internet信息遇到的第一个挑战就是复杂信息的管理问题，Internet的出现将”数据”的概念在实际应用中扩大了。为此，自 1995年起，Informix便着手进行新一代数据库系统的设计。作为专业的数据库厂商，Informix首先针对Internet应用中数据类型的多样化，采用对象技术对关系数据库体系进行了扩展。与众不同之处在于，Informix并非将新的数据类型写死在数据库核心中，而是将数据库系统中各个环节充分地抽象化，使用户有能力定义和描述自己需要管理的数据类型，将可管理的数据类型扩展到无限，同时适应了未来应用发展的需要。这就是Informix今年新推出的数据库服务器–InformixDynamicServer.2000（简称IDS.2000）。</p><p>在IDS.2000中，Informix的另一重大贡献在于抽象化数据库的访问方法（索引机制和查询优化）并将其中接口开放。这样，用户便可以自己定义对复杂对象的全新的索引机制，并融入整个数据库服务器。在IDS.2000中，所有用户自定义的数据类型、操作、索引机制都将被系统与其内置的类型、操作和索引机制同等对待。IDS.2000将所有数据库操作纳入标准数据库SQL的范畴，在形式上与传统关系数据库完全兼容，但适应了”数据”概念拓展的需求，成为真正的通用数据库。Informix在IDS.2000之上增加了一系列核心扩展模块，构成了面向Internet的多功能数据库服务器 Informix Internet Foundation.2000。</p><p>INFORMIX主要产品分为三大部分：<br>　　 数据库服务器(数据库核心)<br>　　 应用开发工具<br>　　 网络数据库互联产品</p><p>数据库服务器有两种，作用都是提供数据操作和管理：<br>　　 SE：完全基于UNIX操作系统，主要针对非多媒体的较少用户数的应用<br>　　 ONLINE：针对大量用户的联机事务处理和多媒体应用环境</p><p>应用开发工具是用以开发应用程序必要的环境和工具，主要也有两个系列：<br>4GL：INFORMIX传统的基于字符界面的开发工具，该系列的主要产品有五个，他们是I-SQL、4GL RDS、4GL C COMPILER、4GL ID和ESQL&#x2F;C；<br>NewEra：INFORMIX最新提供的具有事件驱动能力、面向对象的基于各种图形界面的开发工具。<br>INFORMIX的网络数据库互联产品：提供给用户基于多种工业标准的应用程序接口，通过它可以和其它遵守这些工业标准的数据库联接。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Informix在1980年成立，目的是为Unix等开放操作系统提供专业的关系型数据库产品。公司的名称Informix便是取自Information和Unix的结合。&lt;/p&gt;
&lt;p&gt;Informix第一个真正支持SQL语言的关系数据库产品是InformixSE（Standa</summary>
      
    
    
    
    <category term="数据库" scheme="http://xiejing2014.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    
    <category term="informix" scheme="http://xiejing2014.github.io/tags/informix/"/>
    
  </entry>
  
  <entry>
    <title>Informix历史（转帖-1）</title>
    <link href="http://xiejing2014.github.io/2018/05/25/informix%E5%8E%86%E5%8F%B2%EF%BC%88%E8%BD%AC%E5%B8%96-1%EF%BC%89/"/>
    <id>http://xiejing2014.github.io/2018/05/25/informix%E5%8E%86%E5%8F%B2%EF%BC%88%E8%BD%AC%E5%B8%96-1%EF%BC%89/</id>
    <published>2018-05-25T09:17:51.000Z</published>
    <updated>2018-06-01T05:43:18.000Z</updated>
    
    <content type="html"><![CDATA[<p><strong><font color=steelblue>1980</font></strong><br>在一家早期的S-100&#x2F;CP&#x2F;M公司Cromemco工作的Roger Sippl和Laura King开发了一个基于ISAM技术的小型的关系数据库，作为一个报表记录器软件的一部分。<br>1980年，Sippl和King离开Cromemco去开发关系数据库系统（RDS）。他们的第一个<br>INFORMIX<br>INFORMIX<br>产品叫做马拉松（Marathon），本质上是一个他们以前那个ISAM作品的16位版本，并且在Onyx操作系统上发布，这种Onyx操作系统是一个为早期的ZiLOG微处理器开发的Unix操作系统。<br>在开发RDS的时候，他们把目光转移到了新兴的RDBMS市场，并且在1981年发布了他们自己的一个产品：Informix（INFORMation on unIX）。它包含了他们自己的Informer语言。它具备了ACE报表记录器的特性，用来把数据从数据库里释放出来，并且呈现给用户以供读取。它还具备了PERFORM屏幕格式工具的特性，可以让用户实现交互式的查询并且编辑数据库里的数据。这个产品的最终版本是1986年的3.30版。<br>在1985年，他们引进了一种新的基于SQL的查询引擎，作为INFORMIX-SQL（或ISQL）1.10版（1.00版一直没有发行）的一部分。这个产品同样包括了SQL和PERFORM的SQL变量。ISQL和早期的Informix产品最显著的区别就在于将数据库存取码分散至一个引擎进程中（sqlexec），而不是将其直接嵌入客户端，这样来为和用户的电脑分离开的数据库服务器上的客户端-服务端运算创造条件。而基础的基于ISAM的文件存储引擎就被称作C-ISAM。<br>尽管在上世纪80年代Informix一直扮演一个小角色，但是随着Unix和SQL在80年代走向流行，他们的命运随之改变。在1986年，他们已经强大到自己独立募股，而且将公司改名为Informix Software。他们的产品包括INFORMIX-SQL 2.00版和INFORMIX-4GL 1.00版，两个产品都包含了数据库引擎和开发工具（为程序员准备的I4GL，和为普通用户准备的ISQL）。<br>一系列的产品随之发布，包括最初被认为是INFORMIX-Turbo的新的查询引擎。Turbo利用了新式的，比C-ISAM更对多用户性能有好处的RSAM。在1989年的4.00版出版后，Turbo被命名为INFORMIX-OnLine（一部分原因是因为它允许服务器运行在运行时，并且用户正在修改数据，而数据库的备份照样连贯进行），而且最初的基于C-ISAM的服务器被工具（ISQL和I4GL）所分割开来，并且被命名为INFORMIX-SE（标准版）。在1990年年末的时候，Informix OnLine 5.00版本问世，而且包括了完整的对拥有两步式工作提交和存储过程的分布式交易的支持。在5.01版中增加了对触发器的支持。<br><strong><font color=steelblue>1988</font></strong><br>在1988年，Informix将Innovative Software公司收购，后者研发了著名的基于DOS和Unix的办公系统软件SmartWare，和具有革新意义基于Apple Macintosh平台的的电子制表软件WingZ。<br><strong><font color=steelblue>1994</font></strong><br>随着Informix在办公自动化领域的失败，1994年他们重新把精力集中到发展当中的数据库服务器市场。同年，在与Sequent Computer Systems的协作下，Infomix发布了具备动态可扩展结构（DSA）的6.00版的数据库服务器。<br>DSA将产品的核心引擎做了很大改动，支持了横向和纵向的并行功能。并且基于和很多先驱与软件生产商（比如Sun Microsystems，Hewlett-Packard）都相继追随的对称多处理系统完美搭配的多线程核心。这两种并行模式让产品在扩展性上处于市场领先地位，不论是OLTP还是data warehousing。<br>如今我们熟知的Informix Dynamic Server（当初考虑过命名为Obsidian，而后来命名为Informix OnLine Dynamic Server），它的第7版在1994年震撼了市场。当时正式对称多处理技术（SMP）系统刚刚开始盛行，而且Unix已经开始变为服务器操作系统的主流。第7版基本上成为领先于其他竞争者的一代产品，而且不断地在性能评测上胜出。这场胜利的结果使得Informix在1997年轻而易举地将Sybase挤下去，登上了数据库世界的亚军宝座。<br>在第7版的成功的基础上，Informix将他们核心数据库研发的投资分为两个焦点。第一个是一开始所谓的XMP（for eXtended Multi-Processing），后来演变成了第8版的生产线，也被称作 XPS（for eXtended Parallel Server）。这个焦点致力于data warehousing和高端平台的并行处理，包括像IBM的RS-6000&#x2F;SP这样的shared-nothing平台。<br><strong><font color=steelblue>1995</font></strong><br>在1995年收购了IIIustra后，第二个焦点集中在object-relational数据库（O-R）技术。Informix在7.x版本的OnLine产品中集成了IIIustra的O-R映射和DataBlades，结果变成了Informix Universal Server（IUS），或者简单地说，就是第9版。<br>第8版（XPS）和第9版（IUS）都出现在1996年的市场上，令Informix成为第一个内建O-R支持的“big three”数据库公司（另外两个是Oracle和Sybase）。评论家们花了很多心思在DataBlades上，DataBlades后来非常流行，继与IIIustra的合伙后，又有了新架构。这让其他的软件生产商很着急，Oracle在1997年发布了支持时间序列的“嫁接”包，而Sybase让一家第三方公司为其制作了一个没有竞争力的附加产品包。<br><strong><font color=steelblue>1997</font></strong><br>在市场上的失败和公司的管理不当，掩盖了Informix技术上的成功。在1997年愚人节那天，Informix宣布他们第一个季度的收入比预期少了10亿美元。公司CEO Phillip White把这些差额怪罪在未能投入足够的精力在核心数据库业务上，而在object-relational技术上投入了太多资源。紧接着，大量的营业损失和裁员相继而来。Informix重审了1994年到1996年的利润，1990年代中期包括给合伙公司的软件许可证其实很大一部分都没有真正售出到终极用户手中，这样不规范的操作致使公司财政产生了超过20亿美元的泡沫。即使在White 1997年7月离开后，公司在1998年又来了一次财务重审。<br><strong><font color=steelblue>2001</font></strong><br>从2000年开始，Informix历史上的大事件再也不是集中在技术革新上了。从那一年开始，三月份，Informix购买了Ardent Software，一家自己本来就是收购和合并而来的公司。这次收购为他们那个时候已经很多了的数据库引擎又增加了两个多维引擎UniVerse和UniData（被简称为U2），不仅包括Informix传统的产品，还有Red Brick的面向datawarehouse的SQL引擎、100% Java版本的SQL，Cloudscape（后来被绑定在J2EE的参考安装包内）。<br>IBM接管<br>2000年7月，Ardent公司的前任CEO，Peter Gyenes，成为Informix的CEO，并且迅速重整了Informix以让其成为一个更诱人的期待别被别人收购的“猎物”。这样重要的一个决定是要把所有的数据库引擎技术，和应用程序与工具分离开来。<br>在2001年4月，IBM趁着这次重整，提出了一项来自与沃尔玛（Informix最大的客户）的建议，从Informix购买了数据库技术、品牌、未来开发计划（代码名为“Arrowhead”的内部工程）以及和这些相关的超过10万余计的用户基础。剩下的生产应用程序和工具的公司重新命名为Ascential Software。在2005年5月，IBM买下了Ascential，在IBM的Information Management Software的投资组合下重新聚合了Informix的资产。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;&lt;strong&gt;&lt;font color=steelblue&gt;1980&lt;/font&gt;&lt;/strong&gt;&lt;br&gt;在一家早期的S-100&amp;#x2F;CP&amp;#x2F;M公司Cromemco工作的Roger Sippl和Laura King开发了一个基于ISAM技术的小型的关系数据库</summary>
      
    
    
    
    <category term="数据库" scheme="http://xiejing2014.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    
    <category term="informix" scheme="http://xiejing2014.github.io/tags/informix/"/>
    
  </entry>
  
  <entry>
    <title>Oracle正则表达式函数</title>
    <link href="http://xiejing2014.github.io/2018/05/25/Oracle%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%87%BD%E6%95%B0/"/>
    <id>http://xiejing2014.github.io/2018/05/25/Oracle%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%87%BD%E6%95%B0/</id>
    <published>2018-05-25T03:25:46.000Z</published>
    <updated>2022-05-30T02:19:29.647Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/oracle_12c.jpg" alt="oracle12c"></p><p><escape><span id="more"></span></escape></p><p>Oracle使用正则表达式的4个主要函数：</p><p>1、regexp_like 只能用于条件表达式，和 like 类似，但是使用的正则表达式进行匹配，语法很简单：<br><img src="/images/oracle_regex/20100918104143377.gif"></p><p>2、regexp_substr 函数，和 substr 类似，用于拾取合符正则表达式描述的字符子串，语法如下：<br><img src="/images/oracle_regex/20100918104143840.gif"></p><p>3、regexp_instr 函数，和 instr 类似，用于标定符合正则表达式的字符子串的开始位置，语法如下：<br><img src="/images/oracle_regex/20100918104143534.gif"></p><p>4、regexp_replace 函数，和 replace 类似，用于替换符合正则表达式的字符串，语法如下：<br><img src="/images/oracle_regex/20100918104144147.gif"></p><p>这里解析一下几个参数的含义：</p><p>1、source_char，输入的字符串，可以是列名或者字符串常量、变量。</p><p>2、pattern，正则表达式。</p><p>3、match_parameter，匹配选项。</p><p>取值范围： i：大小写不敏感； c：大小写敏感；n：点号 . 不匹配换行符号；m：多行模式；x：扩展模式，忽略正则表达式中的空白字符。</p><p>4、position，标识从第几个字符开始正则表达式匹配。</p><p>5、occurrence，标识第几个匹配组。</p><p>6、replace_string，替换的字符串。</p><p><strong>示例：</strong></p><p><strong>基础数据准备</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">-- 创建表及测试数据</span><br><span class="line">create table tmp (</span><br><span class="line">  ID varchar2(60),</span><br><span class="line">  STR varchar2(60)</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">insert into tmp values (&#x27;like&#x27;,&#x27;a9999&#x27;);</span><br><span class="line">insert into tmp values (&#x27;like&#x27;,&#x27;a9c&#x27;);</span><br><span class="line">insert into tmp values (&#x27;like&#x27;,&#x27;A7007&#x27;);</span><br><span class="line">insert into tmp values (&#x27;like&#x27;,&#x27;123a34cc&#x27;);</span><br><span class="line">insert into tmp values (&#x27;substr&#x27;,&#x27;123,234,345&#x27;);</span><br><span class="line">insert into tmp values (&#x27;substr&#x27;,&#x27;12,34.56:78&#x27;);</span><br><span class="line">insert into tmp values (&#x27;substr&#x27;,&#x27;123456789&#x27;);</span><br><span class="line">insert into tmp values (&#x27;instr&#x27;,&#x27;192.168.0.1&#x27;);</span><br><span class="line">insert into tmp values (&#x27;replace&#x27;,&#x27;(020)12345678&#x27;);</span><br><span class="line">insert into tmp values (&#x27;replace&#x27;,&#x27;001517729C28&#x27;);</span><br><span class="line"></span><br><span class="line">-- 查询插入结果</span><br><span class="line">SQL&gt; select count(*) from tmp;</span><br><span class="line"></span><br><span class="line">  COUNT(*)</span><br><span class="line">----------</span><br><span class="line">        10</span><br></pre></td></tr></table></figure><p><strong>regexp_like</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line">-- regexp_like示例</span><br><span class="line">-- &#x27;i&#x27;忽略大小写</span><br><span class="line">SQL&gt; SELECT str from tmp where id=&#x27;like&#x27; and regexp_like(str,&#x27;A\d+&#x27;,&#x27;i&#x27;);</span><br><span class="line"></span><br><span class="line">STR</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">a9999</span><br><span class="line">a9c</span><br><span class="line">A7007</span><br><span class="line">123a34cc</span><br><span class="line"></span><br><span class="line">-- 不带&#x27;c&#x27;</span><br><span class="line">SQL&gt; select str from tmp where id=&#x27;like&#x27; and regexp_like(str, &#x27;a\d+&#x27;);</span><br><span class="line"></span><br><span class="line">STR</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">a9999</span><br><span class="line">a9c</span><br><span class="line">123a34cc</span><br><span class="line"></span><br><span class="line">-- 带&#x27;c&#x27;</span><br><span class="line">SQL&gt; SELECT str from tmp where id=&#x27;like&#x27; and regexp_like(str,&#x27;A\d+&#x27;,&#x27;c&#x27;);    </span><br><span class="line"></span><br><span class="line">STR</span><br><span class="line">--------------------</span><br><span class="line">A7007</span><br><span class="line"></span><br><span class="line">-- 匹配以a开头的</span><br><span class="line">SQL&gt; select str from tmp where id=&#x27;like&#x27; and regexp_like(str,&#x27;^a\d+&#x27;);</span><br><span class="line"></span><br><span class="line">STR</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">a9999</span><br><span class="line">a9c</span><br><span class="line"></span><br><span class="line">-- 匹配以a开头，以数字结尾的</span><br><span class="line">SQL&gt; SELECT str from tmp where id=&#x27;like&#x27; and regexp_like(str,&#x27;^a\d+$&#x27;);</span><br><span class="line"></span><br><span class="line">STR</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">a9999</span><br></pre></td></tr></table></figure><p><strong>regexp_substr</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">-- regexp_substr示例1</span><br><span class="line">SELECT</span><br><span class="line">str,</span><br><span class="line">regexp_substr(str,&#x27;[^,]+&#x27;)     str_1_1,</span><br><span class="line">regexp_substr(str,&#x27;[^,]+&#x27;,1,1) str_1_1,</span><br><span class="line">regexp_substr(str,&#x27;[^,]+&#x27;,1,2) str_1_2,  -- occurrence 第几个匹配组</span><br><span class="line">regexp_substr(str,&#x27;[^,]+&#x27;,2,1) str_2_1   -- position 从第几个字符开始匹配</span><br><span class="line">from tmp</span><br><span class="line">where id=&#x27;substr&#x27;;</span><br></pre></td></tr></table></figure><p>查询结果：<br><img src="/images/oracle_regex/11.png"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">-- regexp_substr示例2</span><br><span class="line">SQL&gt; col str format a20</span><br><span class="line">SQL&gt; SELECT</span><br><span class="line">  2  STR,</span><br><span class="line">  3  REGEXP_SUBSTR(STR, &#x27;\d&#x27;) STR,</span><br><span class="line">  4  REGEXP_SUBSTR(STR, &#x27;\d+&#x27;, 1, 1) STR,</span><br><span class="line">  5  REGEXP_SUBSTR(STR, &#x27;\d&#123;2&#125;&#x27;, 1, 2) STR,</span><br><span class="line">  6  REGEXP_SUBSTR(STR, &#x27;\d&#123;3&#125;&#x27;, 2, 1) STR</span><br><span class="line">  7  FROM TMP</span><br><span class="line">  8  WHERE ID = &#x27;substr&#x27;;</span><br></pre></td></tr></table></figure><p>查询结果：<br><img src="/images/oracle_regex/22.png"></p><p><strong>regexp_instr</strong></p><p>略，以后补充。</p><p><strong>regexp_replace</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">-- regexp_replace示例</span><br><span class="line">SELECT STR,</span><br><span class="line">REGEXP_REPLACE(STR, &#x27;020&#x27;, &#x27;GZ&#x27;) STR,</span><br><span class="line">REGEXP_REPLACE(STR, &#x27;(\d&#123;3&#125;)(\d&#123;3&#125;)&#x27;, &#x27;&lt;\2\1&gt;&#x27;) STR -- 将第一、第二捕获组交换位置，用尖括号标识出来</span><br><span class="line">FROM TMP</span><br><span class="line">WHERE ID = &#x27;replace&#x27;;</span><br></pre></td></tr></table></figure><p>查询结果：<br><img src="/images/oracle_regex/33.png"></p><p><strong>综合示例</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">-- 建表</span><br><span class="line">create table tmp1(</span><br><span class="line">id varchar2(60),</span><br><span class="line">str varchar2(512)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">-- 插入测试数据</span><br><span class="line">insert into tmp1 values(&#x27;test&#x27;,&#x27;020000080568179234090000010030040050040205090070080040050000060289634175010000020&#x27;);</span><br><span class="line"></span><br><span class="line">-- 使用regex函数处理数据</span><br><span class="line">SQL&gt; select str,REGEXP_SUBSTR(str,&#x27;\d&#123;9&#125;&#x27;) as row_line from tmp1; </span><br><span class="line"></span><br><span class="line">STR                  ROW_LINE</span><br><span class="line">02000008056817923409 020000080</span><br><span class="line">00000100300400500402</span><br><span class="line">05090070080040050000</span><br><span class="line">060289634</span><br><span class="line"></span><br><span class="line">-- 未完待续</span><br></pre></td></tr></table></figure><p>查询结果：<br><img src="/images/oracle_regex/44.png"></p><p><strong>参考资源：</strong><br><a href="https://www.cnblogs.com/suinlove/p/3981454.html">https://www.cnblogs.com/suinlove/p/3981454.html</a></p><p><a href="https://docs.oracle.com/database/121/SQLRF/conditions007.htm#SQLRF00501">https://docs.oracle.com/database/121/SQLRF/conditions007.htm#SQLRF00501</a></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/oracle_12c.jpg&quot; alt=&quot;oracle12c&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;escape&gt;</summary>
    
    
    
    <category term="数据库" scheme="http://xiejing2014.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    
    <category term="oracle" scheme="http://xiejing2014.github.io/tags/oracle/"/>
    
    <category term="regex" scheme="http://xiejing2014.github.io/tags/regex/"/>
    
  </entry>
  
  <entry>
    <title>分享1文,30分钟速览Regex正则表达式</title>
    <link href="http://xiejing2014.github.io/2018/05/23/%E5%88%86%E4%BA%AB1%E6%96%87-30%E5%88%86%E9%92%9F%E9%80%9F%E8%A7%88Regex%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
    <id>http://xiejing2014.github.io/2018/05/23/%E5%88%86%E4%BA%AB1%E6%96%87-30%E5%88%86%E9%92%9F%E9%80%9F%E8%A7%88Regex%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/</id>
    <published>2018-05-23T01:31:48.000Z</published>
    <updated>2022-05-30T02:19:13.402Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/Regex.jpg"></p><p><escape><span id="more"></span></escape><br>最初接触正则表达式是在学习shell的时候，涉及到正则表达式的匹配。<br>后来，正则表达式在各处用得也逐渐开始多了起来。。<br>分享此文，记录一下。</p><p><strong>资料参考：</strong><a href="http://www.jb51.net/tools/zhengze.html">http://www.jb51.net/tools/zhengze.html</a></p><p><strong>备注：以后遇到正则相关的内容或者一些开发中的问题，可以往本文添加。</strong></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/Regex.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;escape&gt;</summary>
    
    
    
    <category term="关联知识点" scheme="http://xiejing2014.github.io/categories/%E5%85%B3%E8%81%94%E7%9F%A5%E8%AF%86%E7%82%B9/"/>
    
    
    <category term="正则表达式" scheme="http://xiejing2014.github.io/tags/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"/>
    
  </entry>
  
  <entry>
    <title>clearcase常用命令</title>
    <link href="http://xiejing2014.github.io/2018/05/22/clearcase%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/"/>
    <id>http://xiejing2014.github.io/2018/05/22/clearcase%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/</id>
    <published>2018-05-22T12:37:00.000Z</published>
    <updated>2018-05-25T01:43:24.000Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/cc_1.jpg"></p><p><escape><span id="more"></span></escape></p><h1 id="1-常规操作"><a href="#1-常规操作" class="headerlink" title="1. 常规操作"></a>1. 常规操作</h1><h2 id="1-1-最基本的操作"><a href="#1-1-最基本的操作" class="headerlink" title="1.1 最基本的操作"></a>1.1 最基本的操作</h2><p>cleartool co -nc xxx.cpp<br>cleartool ci -nc xxx.cpp</p><h2 id="1-2-查看自己总共co了多少文件"><a href="#1-2-查看自己总共co了多少文件" class="headerlink" title="1.2 查看自己总共co了多少文件"></a>1.2 查看自己总共co了多少文件</h2><p>cleartool lscheckout -cview -me -avobs</p><h2 id="1-3-最有用的命令"><a href="#1-3-最有用的命令" class="headerlink" title="1.3 最有用的命令"></a>1.3 最有用的命令</h2><p>cleartool man xxx<br>cleartool help xxx</p><h2 id="1-4-新增目录和文件"><a href="#1-4-新增目录和文件" class="headerlink" title="1.4 新增目录和文件"></a>1.4 新增目录和文件</h2><p>cleartool mkdir -c comment new_dir<br>cleartool mkelem -c comment new_file.cpp</p><h2 id="1-5-放弃co某个文件"><a href="#1-5-放弃co某个文件" class="headerlink" title="1.5 放弃co某个文件"></a>1.5 放弃co某个文件</h2><p>cleartool unco -keep file.cpp           &#x2F;&#x2F;保留当前所改动的文件<br>cleartool unco -rm   file.cpp</p><h2 id="1-6-主线、分支文件合并"><a href="#1-6-主线、分支文件合并" class="headerlink" title="1.6 主线、分支文件合并"></a>1.6 主线、分支文件合并</h2><p>&#x2F;&#x2F;查找需要合并的文件<br>cleartool findmerge . -fversion &#x2F;main&#x2F;xxxx_path -print<br>&#x2F;&#x2F;比较文件不同<br>cleartool diff file.cpp file.cpp@@&#x2F;main&#x2F;xxxx_path&#x2F;LATEST<br>&#x2F;&#x2F;查看最新版本<br>cleartool lsvtree file.cpp<br>&#x2F;&#x2F;合并<br>cleartool merge -to file.cpp file.cpp@@&#x2F;main&#x2F;xxxx_path&#x2F;LATEST file.cpp@@&#x2F;main&#x2F;LATEST</p><h2 id="1-7-标签相关"><a href="#1-7-标签相关" class="headerlink" title="1.7 标签相关"></a>1.7 标签相关</h2><p>&#x2F;&#x2F;新建标签<br>cleartool mklbtype -nc TEST_LABEL<br>&#x2F;&#x2F;给文件打标签<br>cleartool mklabel -r TEST_LABEL file.cpp<br>&#x2F;&#x2F;删除标签<br>cleartool rmtype lbtype:TEST_LABEL<br>&#x2F;&#x2F;给所有打上TEST_LABEL标签的文件打上TEST_LABEL2标签<br>cleartool mklabel -replace -version &#x2F;main&#x2F;TEST_LABEL TEST_LABEL2 *<br>&#x2F;&#x2F;查找打上TEST_LABEL标签的所有文件<br>cleartool find . -version “lbtype(TEST_LABEL)” -print<br>&#x2F;&#x2F;查找打上TEST_LABEL和TEST_LABEL2标签的文件<br>cleartool find . -element ‘lbtype_sub(TEST_LABEL) &amp;&amp; lbtype_sub(TEST_LABEL2)’ -print</p><h2 id="1-8-将整个目录导入clearcase"><a href="#1-8-将整个目录导入clearcase" class="headerlink" title="1.8 将整个目录导入clearcase"></a>1.8 将整个目录导入clearcase</h2><p>clearfsimport -recurse &#x2F;xxx&#x2F;xxx&#x2F;xxx&#x2F;src &#x2F;view&#x2F;zhuj&#x2F;home&#x2F;vobs&#x2F;cc_account<br>&#x2F;xxx&#x2F;xxx&#x2F;xxx&#x2F;src目录（包括此目录下的所有目录和文件）被导入&#x2F;view&#x2F;zhuj&#x2F;home&#x2F;vobs&#x2F;cc_account中（&#x2F;view&#x2F;zhuj&#x2F;home&#x2F;vobs&#x2F;cc_account&#x2F;src）</p><h1 id="2-clearcase常用命令集锦"><a href="#2-clearcase常用命令集锦" class="headerlink" title="2. clearcase常用命令集锦"></a>2. clearcase常用命令集锦</h1><h2 id="2-1-将整个目录导入clearcase"><a href="#2-1-将整个目录导入clearcase" class="headerlink" title="2.1 将整个目录导入clearcase"></a>2.1 将整个目录导入clearcase</h2><p>clearfsimport -r‘源路径’ ‘目标路径’</p><h2 id="2-2-加锁"><a href="#2-2-加锁" class="headerlink" title="2.2 加锁"></a>2.2 加锁</h2><p>find . -name ‘<em>.</em>‘ -exec ‘cleartool lock nuser userame1,username2 “%CLEARCASE_PN%”‘</p><h2 id="2-3-解锁"><a href="#2-3-解锁" class="headerlink" title="2.3 解锁"></a>2.3 解锁</h2><p>find . -name ‘<em>.</em>‘ -exec ‘cleartool unlock “%CLEARCASE_PN%”‘</p><h2 id="2-4-转换格式"><a href="#2-4-转换格式" class="headerlink" title="2.4 转换格式"></a>2.4 转换格式</h2><p>chtype -f compressed_file “fileName”</p><h2 id="2-5-查看VOB的基本信息和UUID"><a href="#2-5-查看VOB的基本信息和UUID" class="headerlink" title="2.5 查看VOB的基本信息和UUID"></a>2.5 查看VOB的基本信息和UUID</h2><p>des -l vob:.</p><h2 id="2-6-删除视图"><a href="#2-6-删除视图" class="headerlink" title="2.6 删除视图"></a>2.6 删除视图</h2><p>rmview -uuid “UUID”</p><h2 id="2-7-删除lost-found"><a href="#2-7-删除lost-found" class="headerlink" title="2.7 删除lost+found"></a>2.7 删除lost+found</h2><p>find . -name ‘<em>.</em>‘ -exec ‘cleartool rmelem -f “%CLEARCASE_PN%”‘</p><h2 id="2-8-查询某一天的修改记录"><a href="#2-8-查询某一天的修改记录" class="headerlink" title="2.8 查询某一天的修改记录"></a>2.8 查询某一天的修改记录</h2><p>cleartool lshis -r -since 07-dec</p><h2 id="2-9-最基本的操作"><a href="#2-9-最基本的操作" class="headerlink" title="2.9 最基本的操作"></a>2.9 最基本的操作</h2><p>cleartool co -nc filename<br>cleartool ci -nc filename</p><h2 id="2-10-查看自己总共co了多少文件"><a href="#2-10-查看自己总共co了多少文件" class="headerlink" title="2.10 查看自己总共co了多少文件"></a>2.10 查看自己总共co了多少文件</h2><p>cleartool lscheckout -cview –me -vobs</p><h2 id="2-11-make目录和文件"><a href="#2-11-make目录和文件" class="headerlink" title="2.11 make目录和文件"></a>2.11 make目录和文件</h2><p>cleartool mkdir -c comment newdirectory<br>cleartool mkelem -c comment newfilename</p><h2 id="2-12-主线、分支文件合并"><a href="#2-12-主线、分支文件合并" class="headerlink" title="2.12 主线、分支文件合并"></a>2.12 主线、分支文件合并</h2><p>&#x2F;&#x2F;查找需要合并的文件<br>cleartool findmerge . -fversion &#x2F;main&#x2F;TEST_Path -print<br>&#x2F;&#x2F;比较文件不同<br>cleartool diff filename [url&#x3D;mailto:file.cpp@@&#x2F;main&#x2F;xxxx_path&#x2F;LATEST]filename@@&#x2F;main&#x2F;TEST_Path&#x2F;LATEST<br>&#x2F;&#x2F;查看最新版本<br>cleartool lsvtree filename<br>&#x2F;&#x2F;合并<br>cleartool merge -to filename [url&#x3D;mailto:file.cpp@@&#x2F;main&#x2F;xxxx_path&#x2F;LATEST]filename @@&#x2F;main&#x2F;TEST_path&#x2F;LATEST [url&#x3D;mailto:file.cpp@@&#x2F;main&#x2F;LATEST]filename @@&#x2F;main&#x2F;LATEST</p><h2 id="2-13-标签相关"><a href="#2-13-标签相关" class="headerlink" title="2.13 标签相关"></a>2.13 标签相关</h2><p>cleartool mklbtype -nc TEST_LABEL<br>cleartool mklabel -r TEST_LABEL filename<br>cleartool rmtype lbtype:TEST_LABEL<br>&#x2F;&#x2F;给所有打上TEST_LABEL标签的文件打上TEST_LABEL标签<br>cleartool mklabel -replace -version &#x2F;main&#x2F;TEST_LABEL TEST_LABEL *<br>&#x2F;&#x2F;查找打上TEST_LABEL标签的所有文件<br>cleartool find . -version “lbtype(TEST_LABEL)” -print<br>&#x2F;&#x2F;查找打上TEST_LABEL和TEST_LABEL1标签的文件<br>cleartool find . -element ‘lbtype_sub(TEST_LABEL) &amp;&amp; lbtype_sub(TEST_LABEL1)’ -print</p><h2 id="2-14-察看某目录下的文件"><a href="#2-14-察看某目录下的文件" class="headerlink" title="2.14 察看某目录下的文件"></a>2.14 察看某目录下的文件</h2><p>ls</p><h2 id="2-15-man-x2F-help命令"><a href="#2-15-man-x2F-help命令" class="headerlink" title="2.15 man&#x2F;help命令"></a>2.15 man&#x2F;help命令</h2><p>cleartool man xxx<br>cleartool help xxx</p><h2 id="2-16-放弃co某个文件"><a href="#2-16-放弃co某个文件" class="headerlink" title="2.16 放弃co某个文件"></a>2.16 放弃co某个文件</h2><p>cleartool unco -keep filename<br>cleartool unco -rm filename</p><h2 id="2-17-更改VOB的Owner"><a href="#2-17-更改VOB的Owner" class="headerlink" title="2.17 更改VOB的Owner:"></a>2.17 更改VOB的Owner:</h2><p>cleartool protectvob –chown root &#x2F;vob&#x2F;vob.vbs</p><h2 id="2-18-更改VOB的Group"><a href="#2-18-更改VOB的Group" class="headerlink" title="2.18 更改VOB的Group:"></a>2.18 更改VOB的Group:</h2><p>cleartool protectvob –chgrp alluser &#x2F;vob&#x2F;vob.vbs</p><h2 id="2-19-增加Additional-Group"><a href="#2-19-增加Additional-Group" class="headerlink" title="2.19 增加Additional Group:"></a>2.19 增加Additional Group:</h2><p>cleartool protectvob –add_group group1 &#x2F;vob&#x2F;vob.vbs</p><h2 id="2-20-删除Additional-Group"><a href="#2-20-删除Additional-Group" class="headerlink" title="2.20 删除Additional Group:"></a>2.20 删除Additional Group:</h2><p>cleartool protectvob –delete_group group1 &#x2F;vob&#x2F;vob.vbs</p><h2 id="2-21-更改group、owner、mod"><a href="#2-21-更改group、owner、mod" class="headerlink" title="2.21 更改group、owner、mod"></a>2.21 更改group、owner、mod</h2><p>protect -r -chgrp groupname–chown username -chmod 770 .</p><h2 id="2-22-创建VOB"><a href="#2-22-创建VOB" class="headerlink" title="2.22 创建VOB"></a>2.22 创建VOB</h2><p>cleartool mkvob -tag &#x2F;vobtags&#x2F;test_code -c “Test” “D:\Data\Tets.vbs”</p><h2 id="2-23-Mount-vob"><a href="#2-23-Mount-vob" class="headerlink" title="2.23 Mount vob"></a>2.23 Mount vob</h2><p>Cleartool mount &#x2F;vobtags&#x2F;vob </p><h2 id="2-24-创建视图"><a href="#2-24-创建视图" class="headerlink" title="2.24 创建视图"></a>2.24 创建视图</h2><p>cleartool mkview –tag test &#x2F;ccvob&#x2F;views&#x2F;test.vws </p><h2 id="2-25-设置当前视图"><a href="#2-25-设置当前视图" class="headerlink" title="2.25 设置当前视图"></a>2.25 设置当前视图</h2><p>cleartool setview test</p><h2 id="2-26-设置当前的activity"><a href="#2-26-设置当前的activity" class="headerlink" title="2.26 设置当前的activity"></a>2.26 设置当前的activity</h2><p>cleartool setactivity activityname</p><h2 id="2-27-Check-out"><a href="#2-27-Check-out" class="headerlink" title="2.27 Check out"></a>2.27 Check out</h2><p>Check out一个文件</p><p>Cleartool checkout [-reserve][-unreserve] filename</p><p>Check out前目录</p><p>Cleartool checkout .</p><p>Check out当前目录下所有文件</p><p>Cleartool Checkout –nc <em>.</em></p><p>Check out当前目录下所有的文件和目录中的文件</p><p>cleartool find . $file -exec ‘cleartool checkout -nc $CLEARCASE_PN’ </p><h2 id="2-28-Check-in"><a href="#2-28-Check-in" class="headerlink" title="2.28 Check in"></a>2.28 Check in</h2><p>Check in 一个文件</p><p>Cleartool checkin filename</p><p>Check in 当前目录<br>Cleartool checkin .</p><p>Check in 当前目录下所有文件.</p><p>Cleartool Checkin –nc <em>.</em></p><p>Check in当前目录下所有的文件和目录中的文件</p><p>cleartool find . $file -exec ‘cleartool checkin -nc –ide $CLEARCASE_PN’</p><p>以上内容来自：<a href="http://hi.baidu.com/is%CC%EC%B2%C5/blog/item/36bfbfc83cced1117f3e6fa0.html">http://hi.baidu.com/is%CC%EC%B2%C5/blog/item/36bfbfc83cced1117f3e6fa0.html</a></p><h1 id="3-常用命令"><a href="#3-常用命令" class="headerlink" title="3. 常用命令"></a>3. 常用命令</h1><p>创建view：clt mkview -tag view_abcd &#x2F;view_store&#x2F;view_abcd.vws<br>设置view: clt setview view_abcd<br>编辑config specification: clt edcs</p><p>创建branch type：clt mkbrtype dbg_branch1_comments<br>在某个文件的当前branch上， 拉出一个branch：<br>clt mkbranch dbg_branch1_comments filename.c</p><p>now you have make branch on the file, and checked it out.<br>you can edit it with gvim.<br>After changed codes, you can complie it successfully, and test the result, you can check it in.<br>clt ci filename.c<br>If you want to check out it again:<br>clt co filename.c</p><p>To change the branch name to a formula name you can use the command:<br>clt rename brtype:dbg_branch1_comments brtype:crnumber_branch1_comments</p><p>To see the version tree of a file:<br>clt lsvtree -g filename.c</p><p>To see which files is included in a branch, you can edit a script like this find_branch.sh:</p><p>echo “$1”<br>cleartool find -avobs -element “brtype(“$1”)” -nxn -print | xargs cleart<br>ool ls -s|grep “$1”</p><p>To compare files, I write a useful script file mydiff.</p><p>You can use xcc&amp; to open graphic clearcase. So you can do most thing through the menu.</p><p>以上内容来自：<a href="http://www.diybl.com/course/4_webprogram/asp.net/netjs/20071020/78573.html">http://www.diybl.com/course/4_webprogram/asp.net/netjs/20071020/78573.html</a></p><h1 id="4-clearcase实用命令"><a href="#4-clearcase实用命令" class="headerlink" title="4. clearcase实用命令"></a>4. clearcase实用命令</h1><p>查找分支上的文件<br>find . -branch brtype(branchname) -print<br>创建分支<br>mkbrtype -c “comment” branchname<br>创建Label<br>mklbtype -c “comment” labelname<br>用于 cleartool find 查询:<br>cleartool find -all -version “lbtype(REL1)” -print<br>find . -version ‘lbtype(LABEL)’ -print<br>锁分支命令<br>lock brtype:branchname<br>创建trigger<br>trigger已存在<br>mktrtype mktrtype -replace -element -all -preop mkelem -nusers shiquan -exec <a href="http://www.cnblogs.com/samcn/admin/file://192.168.1.5/cc_trigger/false.bat">http://www.cnblogs.com/samcn/admin/file://192.168.1.5/cc_trigger/false.bat</a> NO_RM_MK<br>trigger不存在<br>mktrtype mktrtype -element -all -preop mkelem -nusers shiquan -exec <a href="http://www.cnblogs.com/samcn/admin/file://192.168.1.5/cc_trigger/false.bat">http://www.cnblogs.com/samcn/admin/file://192.168.1.5/cc_trigger/false.bat</a> NO_RM_MK<br>日常开发人员常用命令</p><h1 id="5-开发人员常用命令"><a href="#5-开发人员常用命令" class="headerlink" title="5. 开发人员常用命令"></a>5. 开发人员常用命令</h1><h2 id="5-1-建立vob"><a href="#5-1-建立vob" class="headerlink" title="5.1 建立vob"></a>5.1 建立vob</h2><p>mkvob –tag &#x2F;vobtags&#x2F;vob1 –c “ VOB for project1” &#x2F;vobstore&#x2F;vob1.vbs</p><h2 id="5-2-Mount-vob"><a href="#5-2-Mount-vob" class="headerlink" title="5.2 Mount vob"></a>5.2 Mount vob</h2><p>Cleartool mount &#x2F;vobtags&#x2F;vob1</p><h2 id="5-3-创建视图"><a href="#5-3-创建视图" class="headerlink" title="5.3 创建视图"></a>5.3 创建视图</h2><p>cleartool mkview –tag test1 &#x2F;ccvob&#x2F;views&#x2F;test1.vws</p><h2 id="5-4-设置当前视图"><a href="#5-4-设置当前视图" class="headerlink" title="5.4 设置当前视图"></a>5.4 设置当前视图</h2><p>cleartool setview test1</p><h2 id="5-5-在VOB的根目录下到入数据："><a href="#5-5-在VOB的根目录下到入数据：" class="headerlink" title="5.5 在VOB的根目录下到入数据："></a>5.5 在VOB的根目录下到入数据：</h2><p>clearfsimport –recurse –c “ comments “ &#x2F;home&#x2F;setup&#x2F;* . ，注意命令的最后为圆点，表示当前目录。</p><h2 id="5-6-改变VOB的Owner"><a href="#5-6-改变VOB的Owner" class="headerlink" title="5.6 改变VOB的Owner:"></a>5.6 改变VOB的Owner:</h2><p>cleartool protectvob –chown root &#x2F;vobstore&#x2F;vob1.vbs</p><h2 id="5-7-改变VOB的Group"><a href="#5-7-改变VOB的Group" class="headerlink" title="5.7 改变VOB的Group:"></a>5.7 改变VOB的Group:</h2><p>cleartool protectvob –chgrp alluser &#x2F;vobstore&#x2F;vob1.vbs</p><h2 id="5-8-增加Additional-Group"><a href="#5-8-增加Additional-Group" class="headerlink" title="5.8 增加Additional Group:"></a>5.8 增加Additional Group:</h2><p>cleartool protectvob –add_group group1 &#x2F;vobstore&#x2F;vob1.vbs</p><h2 id="5-9-删除Additional-Group"><a href="#5-9-删除Additional-Group" class="headerlink" title="5.9 删除Additional Group:"></a>5.9 删除Additional Group:</h2><p>cleartool protectvob –delete_group group1 &#x2F;vobstore&#x2F;vob1.vbs<br>修改vob中数据的权限信息</p><h2 id="5-10-将jmccboss-VOB-中所有元素Owner-改成ccadmin，Group改成jmccboss"><a href="#5-10-将jmccboss-VOB-中所有元素Owner-改成ccadmin，Group改成jmccboss" class="headerlink" title="5.10 将jmccboss VOB 中所有元素Owner 改成ccadmin，Group改成jmccboss:"></a>5.10 将jmccboss VOB 中所有元素Owner 改成ccadmin，Group改成jmccboss:</h2><p>Cleartool protect –chown ccadmin –chgrp jmccboss .<br>.为vob根目录</p><h2 id="5-11-将jmccboss-VOB-中所有元素权限"><a href="#5-11-将jmccboss-VOB-中所有元素权限" class="headerlink" title="5.11 将jmccboss VOB 中所有元素权限"></a>5.11 将jmccboss VOB 中所有元素权限</h2><p> 改成对ccadmin（rwx），jmccboss(rwx)，其他VOB附属组成员（r-x）:<br>例： Cleartool protect –recurse –chmod 775 . ，</p><h2 id="5-12-Mount-vob"><a href="#5-12-Mount-vob" class="headerlink" title="5.12 Mount vob"></a>5.12 Mount vob</h2><p>Cleartool mount &#x2F;vobtags&#x2F;vob1</p><h2 id="5-13-创建视图"><a href="#5-13-创建视图" class="headerlink" title="5.13 创建视图"></a>5.13 创建视图</h2><p>cleartool mkview –tag test1 &#x2F;ccvob&#x2F;views&#x2F;test1.vws</p><h2 id="5-14-设置当前视图"><a href="#5-14-设置当前视图" class="headerlink" title="5.14 设置当前视图"></a>5.14 设置当前视图</h2><p>cleartool setview test1</p><h2 id="5-15-在VOB的根目录下到入数据："><a href="#5-15-在VOB的根目录下到入数据：" class="headerlink" title="5.15 在VOB的根目录下到入数据："></a>5.15 在VOB的根目录下到入数据：</h2><p>clearfsimport –recurse –c “ comments “ &#x2F;home&#x2F;setup&#x2F;* . ，注意命令的最后为圆点，表示当前目录。</p><h2 id="5-16-Check-out"><a href="#5-16-Check-out" class="headerlink" title="5.16 Check out"></a>5.16 Check out</h2><p>Cleartool checkout [-reserve][-unreserve] b.c    Check out一个文件<br>Cleartool checkout .   Check out当前目录<br>Cleartool Checkout –nc <em>.</em>    Check out当前目录下所有文件<br>cleartool find . $file -exec ‘cleartool checkout -nc $CLEARCASE_PN’<br>Check out当前目录下所有的文件和目录中的文件</p><h2 id="5-17-Check-in"><a href="#5-17-Check-in" class="headerlink" title="5.17 Check in"></a>5.17 Check in</h2><p>Cleartool checkin b.c    Check in 一个文件<br>Cleartool checkin .    Check in 当前目录<br>Cleartool Checkin –nc <em>.</em>   Check in 当前目录下所有文件.<br>cleartool find . $file -exec ‘cleartool checkin -nc –ide $CLEARCASE_PN’<br>Check in当前目录下所有的文件和目录中的文件 </p><h2 id="5-18-建立一个snapshot-view"><a href="#5-18-建立一个snapshot-view" class="headerlink" title="5.18 建立一个snapshot view"></a>5.18 建立一个snapshot view</h2><p>cleartool mkview –tag pat_2_snapshot_view –snapshot &#x2F;viewstore&#x2F;pat&#x2F;myviews.vws</p><h2 id="5-19-编辑config-spe"><a href="#5-19-编辑config-spe" class="headerlink" title="5.19 编辑config spe"></a>5.19 编辑config spe</h2><p>Cleartool edcs</p><h2 id="5-20-更新snapshot-view"><a href="#5-20-更新snapshot-view" class="headerlink" title="5.20 更新snapshot view"></a>5.20 更新snapshot view</h2><p>cleartool update pat_2_snapshot_view</p><h2 id="5-21-设置当前的activity"><a href="#5-21-设置当前的activity" class="headerlink" title="5.21 设置当前的activity"></a>5.21 设置当前的activity</h2><p>cleartool setactivity activityname<br>      gaibian leixing: chtype binary_delta_file Estonian.r<br>错误 :clearfsimport: Error: Trouble was encountered importing the following elements:<br>        D:\work\shiquan_study\Broadcom070122\BCM_R2.10_A1\mmi\design\gui\res\ffs_preload\CD_5_2_6.dm</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/cc_1.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;escape&gt;</summary>
    
    
    
    <category term="软件版本管理" scheme="http://xiejing2014.github.io/categories/%E8%BD%AF%E4%BB%B6%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86/"/>
    
    
    <category term="clearcase" scheme="http://xiejing2014.github.io/tags/clearcase/"/>
    
  </entry>
  
  <entry>
    <title>Oracle某些函数学习记录（2018-05-21备忘）</title>
    <link href="http://xiejing2014.github.io/2018/05/21/Oracle%E6%9F%90%E4%BA%9B%E5%87%BD%E6%95%B0%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95%EF%BC%882018-05-21%E5%A4%87%E5%BF%98%EF%BC%89/"/>
    <id>http://xiejing2014.github.io/2018/05/21/Oracle%E6%9F%90%E4%BA%9B%E5%87%BD%E6%95%B0%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95%EF%BC%882018-05-21%E5%A4%87%E5%BF%98%EF%BC%89/</id>
    <published>2018-05-21T10:09:01.000Z</published>
    <updated>2018-05-21T17:11:18.000Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/oracle_12c.jpg" alt="oracle12c"></p><p><escape><span id="more"></span></escape></p><p>最近需要了解一下oracle的有关函数，故寻觅一番，总结如下。</p><p>更多内容参考Oracle官网。<br>以下参考网络资源学习、摘录总结。</p><p>本文使用的本地oracle环境对参考资源进行了学习，当前版本为：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select * from v$version;</span><br><span class="line"></span><br><span class="line">BANNER</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">    CON_ID</span><br><span class="line">----------</span><br><span class="line">Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production</span><br><span class="line">         0</span><br><span class="line"></span><br><span class="line">PL/SQL Release 12.2.0.1.0 - Production</span><br><span class="line">         0</span><br><span class="line"></span><br><span class="line">CORE    12.2.0.1.0      Production</span><br><span class="line">         0</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">BANNER</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">    CON_ID</span><br><span class="line">----------</span><br><span class="line">TNS for Linux: Version 12.2.0.1.0 - Production</span><br><span class="line">         0</span><br><span class="line"></span><br><span class="line">NLSRTL Version 12.2.0.1.0 - Production</span><br><span class="line">         0</span><br></pre></td></tr></table></figure><h1 id="1-DBMS-OBFUSCATION-TOOLKIT-MD5和Utl-Raw-Cast-To-Raw"><a href="#1-DBMS-OBFUSCATION-TOOLKIT-MD5和Utl-Raw-Cast-To-Raw" class="headerlink" title="1. DBMS_OBFUSCATION_TOOLKIT.MD5和Utl_Raw.Cast_To_Raw"></a>1. DBMS_OBFUSCATION_TOOLKIT.MD5和Utl_Raw.Cast_To_Raw</h1><p>DBMS_OBFUSCATION_TOOLKIT.MD5是MD5编码的数据包函数，可以直接在SQL中进行调用。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select Utl_Raw.Cast_To_Raw(sys.dbms_obfuscation_toolkit.md5(input_string =&gt; &#x27;111&#x27;)) from dual;</span><br><span class="line"></span><br><span class="line">UTL_RAW.CAST_TO_RAW(SYS.DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING=&gt;&#x27;111&#x27;))</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">698D51A19D8A121CE581499D7B701668</span><br></pre></td></tr></table></figure><p>其结果返回的字串为RAW类型，要正确显示的话，需要经过Utl_Raw.Cast_To_Raw转换。<br>关于RAW类型，可详见本文第2节说明。</p><h1 id="2-RAW类型"><a href="#2-RAW类型" class="headerlink" title="2. RAW类型"></a>2. RAW类型</h1><p>oracle中用于保存位串的数据类型是RAW或者LONG RAW。<br>RAW类似于CHAR，声明方式为RAW(L)，L为单位，以字节表示，作为数据库列最大为2000，作为变量最大32767字节。<br>LONG RAW，类似于LONG，作为数据库列最大存储2G字节的数据，作为变量最大32760字节<br>RAW类型的好处就是：在网络中的计算机之间传输 RAW 数据时，或者使用 Oracle 实用程序将 RAW 数据从一个数据库移到另一个数据库时，Oracle服务器不执行字符集转换。存储实际列值所需要的字节数大小随每行大小而异，最多为 2000字节。可能这样的数据类型在数据库效率上会提高，而且对数据由于字符集的不同而导致的不一致的可能性在这边也排除了。<br>RAW保存的为16进制数，对应每个字符的ASCII码。常见的两个函数为utl_raw.cast_to_raw([varchar2]) 和utl_raw.cast_to_varchar2([raw])。如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select utl_raw.cast_to_raw(&#x27;甲骨文&#x27;) name from dual;</span><br><span class="line"></span><br><span class="line">NAME</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">E794B2E9AAA8E69687</span><br><span class="line"></span><br><span class="line">SQL&gt; </span><br><span class="line">SQL&gt; select utl_raw.cast_to_varchar2(&#x27;E794B2E9AAA8E69687&#x27;) name  from dual;</span><br><span class="line"></span><br><span class="line">NAME</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">甲骨文</span><br></pre></td></tr></table></figure><p>题外话：使用SQL语句时，注意SERVER端和CLIENT端的字符集得一致，否则查询可能中文乱码。<br>SERVER端：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select userenv(&#x27;language&#x27;) from dual;</span><br><span class="line"></span><br><span class="line">USERENV(&#x27;LANGUAGE&#x27;)</span><br><span class="line">----------------------------------------------------</span><br><span class="line">AMERICAN_CHINA.AL32UTF8</span><br></pre></td></tr></table></figure><p>CLIENT终端调整为显示一致：(如下临时调整)</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">export NLS_LANG=&quot;AMERICAN_CHINA.AL32UTF8&quot;</span><br></pre></td></tr></table></figure><p>调整之后，对应终端能够正常显示中文。</p><p><em><strong>上述1,2节内容亦可参照以下链接：</strong></em><br><a href="https://blog.csdn.net/lwei_998/article/details/6070689">https://blog.csdn.net/lwei_998/article/details/6070689</a><br><a href="https://blog.csdn.net/john2522/article/details/8124087">https://blog.csdn.net/john2522/article/details/8124087</a><br>(或者<a href="https://blog.csdn.net/afzaici/article/details/51669495">https://blog.csdn.net/afzaici/article/details/51669495</a><br><a href="http://blog.chinaunix.net/uid-90674-id-2436668.html">http://blog.chinaunix.net/uid-90674-id-2436668.html</a><br>)</p><h1 id="3-XMLTYPE操作，学习extract-和extractvalue"><a href="#3-XMLTYPE操作，学习extract-和extractvalue" class="headerlink" title="3. XMLTYPE操作，学习extract()和extractvalue()"></a>3. XMLTYPE操作，学习extract()和extractvalue()</h1><h2 id="3-1-特性概述"><a href="#3-1-特性概述" class="headerlink" title="3.1 特性概述"></a>3.1 特性概述</h2><p>对于文件等复杂且大体积的数据对象，Oracle通常采用LOB类型的变量来进行存储。对于XML数据文件，Oracle提供了XMLTYPE的数据类型。xmltype提供了适合的保存、检索和操作的支持。以下为一些特性介绍：<br>作为xmltype，Oracle会在数据表上建立一个clob类型的系统列，用于协助保存数据。<br><em><strong>可参考“xmltype类型浅析”一文：</strong></em><br><a href="https://www.linuxidc.com/Linux/2017-03/141678.htm">https://www.linuxidc.com/Linux/2017-03/141678.htm</a><br><em><strong>对于LOB类型，可参考“Oracle LOB类型介绍”一文：</strong></em><br><a href="https://blog.csdn.net/bbliutao/article/details/19707169">https://blog.csdn.net/bbliutao/article/details/19707169</a></p><h2 id="3-2-XMLTYPE简单操作实例"><a href="#3-2-XMLTYPE简单操作实例" class="headerlink" title="3.2 XMLTYPE简单操作实例"></a>3.2 XMLTYPE简单操作实例</h2><h3 id="3-2-1-创建test-xml文件"><a href="#3-2-1-创建test-xml文件" class="headerlink" title="3.2.1 创建test.xml文件"></a>3.2.1 创建test.xml文件</h3><p>文件路径及名称：&#x2F;home&#x2F;oracle&#x2F;xml&#x2F;test.xml<br>xml格式文件，文件内容如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;</span><br><span class="line">&lt;collection xmlns=&quot;&quot;&gt;</span><br><span class="line">  &lt;record&gt;</span><br><span class="line">    &lt;leader&gt;-----nam0-22-----^^^450-&lt;/leader&gt;</span><br><span class="line">    &lt;datafield tag=&quot;200&quot; ind1=&quot;1&quot; ind2=&quot; &quot;&gt;</span><br><span class="line">      &lt;subfield code=&quot;a&quot;&gt;抗震救灾&lt;/subfield&gt;</span><br><span class="line">       &lt;subfield code=&quot;f&quot;&gt;奥运会&lt;/subfield&gt;</span><br><span class="line">    &lt;/datafield&gt;</span><br><span class="line">    &lt;datafield tag=&quot;209&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;</span><br><span class="line">      &lt;subfield code=&quot;a&quot;&gt;经济学&lt;/subfield&gt;</span><br><span class="line">       &lt;subfield code=&quot;b&quot;&gt;计算机&lt;/subfield&gt;</span><br><span class="line">       &lt;subfield code=&quot;c&quot;&gt;10001&lt;/subfield&gt;</span><br><span class="line">       &lt;subfield code=&quot;d&quot;&gt;2005-07-09&lt;/subfield&gt;</span><br><span class="line">    &lt;/datafield&gt;</span><br><span class="line">    &lt;datafield tag=&quot;610&quot; ind1=&quot;0&quot; ind2=&quot; &quot;&gt;</span><br><span class="line">       &lt;subfield code=&quot;a&quot;&gt;计算机&lt;/subfield&gt;</span><br><span class="line">       &lt;subfield code=&quot;a&quot;&gt;笔记本&lt;/subfield&gt;</span><br><span class="line">    &lt;/datafield&gt;</span><br><span class="line">  &lt;/record&gt;</span><br><span class="line">&lt;/collection&gt;</span><br></pre></td></tr></table></figure><h3 id="3-2-2-创建存放XML文件的表"><a href="#3-2-2-创建存放XML文件的表" class="headerlink" title="3.2.2 创建存放XML文件的表"></a>3.2.2 创建存放XML文件的表</h3><p><strong>建表</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; create table xmlexample(</span><br><span class="line">    ID varchar2(60),</span><br><span class="line">    name varchar2(60),</span><br><span class="line">    data xmltype   </span><br><span class="line">    );</span><br><span class="line"></span><br><span class="line">Table created.</span><br></pre></td></tr></table></figure><p><strong>插入数据</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; create directory XMLPATH_TEST as &#x27;/home/oracle/xml&#x27;;</span><br><span class="line"></span><br><span class="line">Directory created.</span><br><span class="line"></span><br><span class="line">insert into xmlexample(id,name,data)</span><br><span class="line">values(sys_guid(),&#x27;my document&#x27;,</span><br><span class="line">        xmltype</span><br><span class="line">        (</span><br><span class="line">         bfilename(&#x27;XMLPATH_TEST&#x27;,&#x27;test.xml&#x27;),</span><br><span class="line">         nls_charset_id(&#x27;AL32UTF8&#x27;)</span><br><span class="line">        )</span><br><span class="line">);</span><br></pre></td></tr></table></figure><p><strong>查询插入结果</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select * from xmlexample;</span><br><span class="line"></span><br><span class="line">ID</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">NAME</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">DATA</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">6CB32CE193E2D536E055000000000001</span><br><span class="line">my document</span><br><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span><br><span class="line">&lt;collection xmlns=&quot;&quot;&gt;</span><br><span class="line">  &lt;record&gt;</span><br><span class="line">    &lt;lea</span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><h3 id="3-2-3-extractvalue-函数的使用"><a href="#3-2-3-extractvalue-函数的使用" class="headerlink" title="3.2.3 extractvalue()函数的使用"></a>3.2.3 extractvalue()函数的使用</h3><p>Oracle提供对XML文件的检索功能（extractvalue），extractvalue只能返回一个节点的一个值，具体操作方法如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select id,name,extractvalue(x.data,&#x27;/collection/record/leader&#x27;) as A from xmlexample x;</span><br><span class="line"></span><br><span class="line">ID</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">NAME</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">A</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">6CB32CE193E2D536E055000000000001</span><br><span class="line">my document</span><br><span class="line">-----nam0-22-----^^^450-</span><br></pre></td></tr></table></figure><p>如果该节点有两个值，则系统提示错误。</p><h3 id="3-2-4-extract-函数的使用"><a href="#3-2-4-extract-函数的使用" class="headerlink" title="3.2.4 extract()函数的使用"></a>3.2.4 extract()函数的使用</h3><p>如果想查询所有subfield的值就要用到extract()，它可以返回一个节点下的所有值。操作如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select id,name, extract(x.data,&#x27;/collection/record/datafield/subfield&#x27;) as A from xmlexample x;</span><br><span class="line"></span><br><span class="line">ID</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">NAME</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">A</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">6CB32CE193E2D536E055000000000001</span><br><span class="line">my document</span><br><span class="line">&lt;subfield code=&quot;a&quot;&gt;抗震救灾&lt;/subfield&gt;</span><br><span class="line">&lt;subfield code=&quot;f&quot;&gt;奥运会&lt;/subfiel</span><br></pre></td></tr></table></figure><p>可以看到它返回的是XML格式的。如果我们想只返回它的值就要是用两个函数了。</p><h3 id="3-2-5-table和XMLSequence"><a href="#3-2-5-table和XMLSequence" class="headerlink" title="3.2.5 table和XMLSequence"></a>3.2.5 table和XMLSequence</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select extractValue(value(i),&#x27;/subfield&#x27;) xx </span><br><span class="line">  2   from xmlexample x,</span><br><span class="line">  3   table(XMLSequence(extract(x.data,&#x27;/collection/record/datafield/subfield&#x27;))) i;</span><br><span class="line"></span><br><span class="line">XX</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">抗震救灾</span><br><span class="line">奥运会</span><br><span class="line">经济学</span><br><span class="line">计算机</span><br><span class="line">10001</span><br><span class="line">2005-07-09</span><br><span class="line">计算机</span><br><span class="line">笔记本</span><br><span class="line"></span><br><span class="line">8 rows selected.</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><h3 id="3-2-6-检索出特定的节点的特定值"><a href="#3-2-6-检索出特定的节点的特定值" class="headerlink" title="3.2.6 检索出特定的节点的特定值"></a>3.2.6 检索出特定的节点的特定值</h3><p>有时候我们在实际操作的时候并不是检索出所有值，而是根据条件查询出我们所需要的信息。如果我们想检索出</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">&lt;datafield tag=&quot;209&quot; ind1=&quot; &quot; ind2=&quot; &quot;&gt;</span><br><span class="line">&lt;subfield code=&quot;a&quot;&gt;经济学&lt;/subfield&gt;</span><br></pre></td></tr></table></figure><p>中的值-经济学<br>操作如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select id,name,extractvalue(x.data,&#x27;/collection/record/datafield[@tag=&quot;209&quot;]/subfield[@code=&quot;a&quot;]&#x27;) as A </span><br><span class="line">  2  from xmlexample x;</span><br><span class="line"></span><br><span class="line">ID</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">NAME</span><br><span class="line">------------------------------------------------------------</span><br><span class="line">A</span><br><span class="line">--------------------------------------------------------------------------------</span><br><span class="line">6CB32CE193E2D536E055000000000001</span><br><span class="line">my document</span><br><span class="line">经济学</span><br></pre></td></tr></table></figure><h3 id="3-2-7-XMLTYPE小结"><a href="#3-2-7-XMLTYPE小结" class="headerlink" title="3.2.7 XMLTYPE小结"></a>3.2.7 XMLTYPE小结</h3><p>Oracle对于XMLType的操作有很多种，还要靠大家自己去发现。数据库对XML的检索就是把XML的节点当作一个列来检索，而不同的是表里装的是二维的数据，而XML中可以装N维。还有就是，表中列不存在就会提示无效标识符，如果节点不存在，则检索出NULL，不会报错。所以，对与XML文件的操作通常是通过视图来完成。</p><p>以上学习内容参照：<a href="https://www.cnblogs.com/millen/archive/2011/12/28/2304410.html">https://www.cnblogs.com/millen/archive/2011/12/28/2304410.html</a><br>关于Oracle中XML函数的接口介绍，可参见下文：<br><a href="http://huangronaldo.iteye.com/blog/1457567">http://huangronaldo.iteye.com/blog/1457567</a></p><h1 id="4-dbms-job用法"><a href="#4-dbms-job用法" class="headerlink" title="4. dbms_job用法"></a>4. dbms_job用法</h1><p>dbms_job，用于安排和管理作业队列，通过作业控制，使oracle数据库定期执行特定的任务。  </p><h2 id="4-1-dbms-job涉及到的知识点"><a href="#4-1-dbms-job涉及到的知识点" class="headerlink" title="4.1 dbms_job涉及到的知识点"></a>4.1 dbms_job涉及到的知识点</h2><p>1、创建job<br>variable jobno number;<br>dbms_job.submit(:jobno, —-job号<br> ‘your_procedure;’,—-执行的存储过程, ‘;’不能省略<br> next_date, —-下次执行时间<br> ‘interval’ —-每次间隔时间，interval以天为单位<br>);<br>–- 系统会自动分配一个任务号jobno。</p><p>2、删除job: dbms_job.remove(jobno); </p><p>3、修改要执行的操作: job:dbms_job.what(jobno, what);</p><p>4、修改下次执行时间：dbms_job.next_date(jobno, next_date);</p><p>5、修改间隔时间：dbms_job.interval(jobno, interval); </p><p>6、启动job: dbms_job.run(jobno);</p><p>7、停止job: dbms.broken(jobno, broken, nextdate); –broken为boolean值</p><h2 id="4-2-初始化相关参数job-queue-processes"><a href="#4-2-初始化相关参数job-queue-processes" class="headerlink" title="4.2 初始化相关参数job_queue_processes"></a>4.2 初始化相关参数job_queue_processes</h2><p>1、job_queue_process表示oracle能够并发的job的数量，当job_queue_process值为0时表示全部停止oracle的job。</p><p>2、查看job_queue_processes参数<br>方法一：<br>show parameter job_queue_process;<br>方法二：<br>select * from v$parameter where name&#x3D;’job_queue_processes’;</p><p>3、修改job_queue_processes参数（感觉非必须，初始应该有合理值，mark察其用法 by xj）<br>alter system set job_queue_processes &#x3D; 10;</p><h2 id="4-3-user-jobs表结构"><a href="#4-3-user-jobs表结构" class="headerlink" title="4.3 user_jobs表结构"></a>4.3 user_jobs表结构</h2><p>字段（列） 类型 描述<br>job number 任务的唯一标示号<br>log_user varchar2(30) 提交任务的用户<br>priv_user varchar2(30) 赋予任务权限的用户<br>schema_user varchar2(30) 对任务作语法分析的用户模式<br>last_date date 最后一次成功运行任务的时间<br>last_sec varchar2(8) 如hh24:mm:ss格式的last_date日期的小时，分钟和秒<br>this_date date 正在运行任务的开始时间，如果没有运行任务则为null<br>this_sec varchar2(8) 如hh24:mm:ss格式的this_date日期的小时，分钟和秒<br>next_date date 下一次定时运行任务的时间</p><h2 id="4-4-一个dbms-job使用的具体案例"><a href="#4-4-一个dbms-job使用的具体案例" class="headerlink" title="4.4 一个dbms_job使用的具体案例"></a>4.4 一个dbms_job使用的具体案例</h2><h3 id="4-4-1-在plsql中创建表"><a href="#4-4-1-在plsql中创建表" class="headerlink" title="4.4.1 在plsql中创建表"></a>4.4.1 在plsql中创建表</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">create table tt(</span><br><span class="line"> id varchar2(30),</span><br><span class="line"> name varchar2(30)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">Table created.</span><br></pre></td></tr></table></figure><h3 id="4-4-2-在plsql中创建存储过程"><a href="#4-4-2-在plsql中创建存储过程" class="headerlink" title="4.4.2 在plsql中创建存储过程"></a>4.4.2 在plsql中创建存储过程</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">create or replace procedure proce_t is</span><br><span class="line">begin</span><br><span class="line"> insert into tt(id, name) values(&#x27;1&#x27;, to_char(sysdate, &#x27;yyyy-mm-dd hh24:mi:ss&#x27;));</span><br><span class="line"> commit;</span><br><span class="line">end proce_t;</span><br><span class="line">/</span><br><span class="line"></span><br><span class="line">Procedure created.</span><br></pre></td></tr></table></figure><h3 id="4-4-3-创建job任务-1分钟执行一次"><a href="#4-4-3-创建job任务-1分钟执行一次" class="headerlink" title="4.4.3 创建job任务(1分钟执行一次)"></a>4.4.3 创建job任务(1分钟执行一次)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">variable jobno number;</span><br><span class="line">begin</span><br><span class="line"> dbms_job.submit(:jobno,&#x27;proce_t;&#x27;, sysdate, &#x27;sysdate+1/24/60&#x27;);</span><br><span class="line"> commit;</span><br><span class="line">end;</span><br><span class="line">/</span><br><span class="line"></span><br><span class="line">PL/SQL procedure successfully completed.</span><br></pre></td></tr></table></figure><h3 id="4-4-4-跟踪任务的情况-查看任务队列"><a href="#4-4-4-跟踪任务的情况-查看任务队列" class="headerlink" title="4.4.4 跟踪任务的情况(查看任务队列)"></a>4.4.4 跟踪任务的情况(查看任务队列)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select job, next_date, next_sec, failures, broken from user_jobs;</span><br><span class="line"></span><br><span class="line">       JOB NEXT_DATE          NEXT_SEC                           FAILURES B</span><br><span class="line">---------- ------------------ -------------------------------- ---------- -</span><br><span class="line">         1 21-MAY-18          00:26:45                                  0 N</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><p>查看定时任务执行情况。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select * from tt;</span><br><span class="line"></span><br><span class="line">ID                             NAME</span><br><span class="line">------------------------------ ------------------------------</span><br><span class="line">1                              2018-05-21 00:25:45</span><br><span class="line">1                              2018-05-21 00:26:50</span><br><span class="line">1                              2018-05-21 00:27:55</span><br></pre></td></tr></table></figure><h3 id="4-4-5-停止定时任务"><a href="#4-4-5-停止定时任务" class="headerlink" title="4.4.5 停止定时任务"></a>4.4.5 停止定时任务</h3><h4 id="4-4-5-1-查看定时任务的job号"><a href="#4-4-5-1-查看定时任务的job号" class="headerlink" title="4.4.5.1 查看定时任务的job号"></a>4.4.5.1 查看定时任务的job号</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select job, next_date, next_sec, failures, broken from user_jobs;</span><br><span class="line"></span><br><span class="line">       JOB NEXT_DATE          NEXT_SEC                           FAILURES B</span><br><span class="line">---------- ------------------ -------------------------------- ---------- -</span><br><span class="line">         1 21-MAY-18          00:30:00                                  0 N</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><h4 id="4-4-5-2-停止一个已启动的定时任务"><a href="#4-4-5-2-停止一个已启动的定时任务" class="headerlink" title="4.4.5.2 停止一个已启动的定时任务"></a>4.4.5.2 停止一个已启动的定时任务</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">begin</span><br><span class="line"> dbms_job.broken(1, true, sysdate);</span><br><span class="line"> commit;</span><br><span class="line">end;</span><br><span class="line">/</span><br><span class="line">PL/SQL procedure successfully completed.</span><br></pre></td></tr></table></figure><h4 id="4-4-5-3-查看定时任务是否已停止成功"><a href="#4-4-5-3-查看定时任务是否已停止成功" class="headerlink" title="4.4.5.3 查看定时任务是否已停止成功"></a>4.4.5.3 查看定时任务是否已停止成功</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select job, next_date, next_sec, failures, broken from user_jobs;</span><br><span class="line"></span><br><span class="line">       JOB NEXT_DATE          NEXT_SEC                           FAILURES B</span><br><span class="line">---------- ------------------ -------------------------------- ---------- -</span><br><span class="line">         1 01-JAN-00          00:00:00                                  0 Y</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><p>broken值为y，表示定时任务已停止。</p><h3 id="4-4-6-启动定时任务"><a href="#4-4-6-启动定时任务" class="headerlink" title="4.4.6 启动定时任务"></a>4.4.6 启动定时任务</h3><h4 id="4-4-6-1-查看停止定时任务"><a href="#4-4-6-1-查看停止定时任务" class="headerlink" title="4.4.6.1 查看停止定时任务"></a>4.4.6.1 查看停止定时任务</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select job, next_date, next_sec, failures, broken from user_jobs;</span><br><span class="line"></span><br><span class="line">       JOB NEXT_DATE          NEXT_SEC                           FAILURES B</span><br><span class="line">---------- ------------------ -------------------------------- ---------- -</span><br><span class="line">         1 01-JAN-00          00:00:00                                  0 Y</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><p>broken值为y，表示定时任务已停止。</p><h4 id="4-4-6-2-启动定时任务"><a href="#4-4-6-2-启动定时任务" class="headerlink" title="4.4.6.2 启动定时任务"></a>4.4.6.2 启动定时任务</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">begin</span><br><span class="line"> dbms_job.run(1);</span><br><span class="line"> commit;</span><br><span class="line">end;</span><br><span class="line">/</span><br><span class="line">PL/SQL procedure successfully completed.</span><br></pre></td></tr></table></figure><h4 id="4-4-6-3-查看定时任务是否已启动"><a href="#4-4-6-3-查看定时任务是否已启动" class="headerlink" title="4.4.6.3 查看定时任务是否已启动"></a>4.4.6.3 查看定时任务是否已启动</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select job, next_date, next_sec, failures, broken from user_jobs;</span><br><span class="line"></span><br><span class="line">       JOB NEXT_DATE          NEXT_SEC                           FAILURES B</span><br><span class="line">---------- ------------------ -------------------------------- ---------- -</span><br><span class="line">         1 21-MAY-18          00:34:40                                  0 N</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><p>broken值为n，表示定时任务启动成功。</p><h3 id="4-4-7-查看进程数"><a href="#4-4-7-查看进程数" class="headerlink" title="4.4.7 查看进程数"></a>4.4.7 查看进程数</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; show parameter job_queue_processes;</span><br><span class="line"></span><br><span class="line">NAME                                 TYPE        VALUE</span><br><span class="line">------------------------------------ ----------- ------------------------------</span><br><span class="line">job_queue_processes                  integer     4000</span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><p>必须大于0，否则执行下面的命令修改：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">alter system set job_queue_processes=10;</span><br></pre></td></tr></table></figure><h3 id="4-4-8-再创建一个任务-每5分钟执行一次"><a href="#4-4-8-再创建一个任务-每5分钟执行一次" class="headerlink" title="4.4.8 再创建一个任务(每5分钟执行一次)"></a>4.4.8 再创建一个任务(每5分钟执行一次)</h3><p><strong>创建</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">variable jobno number;</span><br><span class="line">begin</span><br><span class="line"> dbms_job.submit(:jobno, &#x27;proce_t;&#x27;, sysdate, &#x27;sysdate+1/24/12&#x27;); --interval是以天为单位的</span><br><span class="line"> commit;</span><br><span class="line">end;</span><br><span class="line">/</span><br></pre></td></tr></table></figure><p><strong>执行</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">SQL&gt; select job,next_date,next_sec,failures,broken from user_jobs;</span><br><span class="line"></span><br><span class="line">       JOB NEXT_DATE          NEXT_SEC                           FAILURES B</span><br><span class="line">---------- ------------------ -------------------------------- ---------- -</span><br><span class="line">         1 21-MAY-18          00:36:50                                  0 N</span><br><span class="line">         2 21-MAY-18          00:41:25                                  0 N</span><br><span class="line"></span><br><span class="line">SQL&gt;</span><br></pre></td></tr></table></figure><h2 id="4-5-job运行时间的总结"><a href="#4-5-job运行时间的总结" class="headerlink" title="4.5 job运行时间的总结"></a>4.5 job运行时间的总结</h2><p>1:每分钟执行<br>Interval &#x3D;&gt; TRUNC(sysdate,’mi’) + 1&#x2F;(24<em>60)<br>2:每天定时执行<br>例如：每天的凌晨1点执行<br>Interval &#x3D;&gt; TRUNC(sysdate) + 1 +1&#x2F;(24)<br>3:每周定时执行<br>例如：每周一凌晨1点执行<br>Interval &#x3D;&gt; TRUNC(next_day(sysdate,’星期一’))+1&#x2F;24<br>4:每月定时执行<br>例如：每月1日凌晨1点执行<br>Interval &#x3D;&gt;TRUNC(LAST_DAY(SYSDATE))+1+1&#x2F;24<br>5:每季度定时执行<br>例如每季度的第一天凌晨1点执行<br>Interval &#x3D;&gt; TRUNC(ADD_MONTHS(SYSDATE,3),’Q’) + 1&#x2F;24<br>6:每半年定时执行<br>例如：每年7月1日和1月1日凌晨1点<br>Interval &#x3D;&gt; ADD_MONTHS(trunc(sysdate,’yyyy’),6)+1&#x2F;24<br>7:每年定时执行<br>例如：每年1月1日凌晨1点执行<br>Interval &#x3D;&gt;ADD_MONTHS(trunc(sysdate,’yyyy’), 12)+1&#x2F;24<br>job的运行频率设置<br>1.每天固定时间运行，比如早上8:10分钟：Trunc(Sysdate+1) + (8</em>60+10)&#x2F;24<em>60<br>2.Toad中提供的：<br>每天：trunc(sysdate+1)<br>每周：trunc(sysdate+7)<br>每月：trunc(sysdate+30)<br>每个星期日：next_day(trunc(sysdate),’星期日’)<br>每天6点：trunc(sysdate+1)+6&#x2F;24<br>半个小时：sysdate+30&#x2F;(24</em>60)<br>3.每个小时的第15分钟运行，比如：8:15，9:15，10:15…：trunc(sysdate,’hh’)+(60+15)&#x2F;(24*60) 。</p><p><em><strong>上文参见：</strong></em><br>oracle数据库定时任务dbms_job的用法详解<br><a href="http://www.jb51.net/article/92575.htm">http://www.jb51.net/article/92575.htm</a></p><p><em><strong>更多详情可参见以下两篇文章，有关于CHANGE的介绍。</strong></em></p><p><em>更多dbms_job包的说明：</em><br><a href="http://wallimn.iteye.com/blog/519924">http://wallimn.iteye.com/blog/519924</a></p><p><strong>PS:</strong><br>change实际就是改变当前某个job设置的工作参数，包括job、what、next_date和interval参数。<br>job参数是一个整数值，它唯一标识此工作。<br>what参数是由此工作运行的一块PL&#x2F;SQL代码块。<br>next_date参数指示何时此工作将被执行。<br>interval参数指示一个工作重执行的频度。</p><p><em>关于一些参数的解释可以参照一下：</em><br><a href="https://www.cnblogs.com/chenjunjie/p/5054415.html">https://www.cnblogs.com/chenjunjie/p/5054415.html</a></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/oracle_12c.jpg&quot; alt=&quot;oracle12c&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;escape&gt;</summary>
    
    
    
    <category term="数据库" scheme="http://xiejing2014.github.io/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
    
    
    <category term="oracle" scheme="http://xiejing2014.github.io/tags/oracle/"/>
    
    <category term="oracle function" scheme="http://xiejing2014.github.io/tags/oracle-function/"/>
    
  </entry>
  
  <entry>
    <title>用不同语言来遍历目录和文件</title>
    <link href="http://xiejing2014.github.io/2018/05/18/%E7%94%A8%E4%B8%8D%E5%90%8C%E8%AF%AD%E8%A8%80%E6%9D%A5%E9%81%8D%E5%8E%86%E7%9B%AE%E5%BD%95%E5%92%8C%E6%96%87%E4%BB%B6/"/>
    <id>http://xiejing2014.github.io/2018/05/18/%E7%94%A8%E4%B8%8D%E5%90%8C%E8%AF%AD%E8%A8%80%E6%9D%A5%E9%81%8D%E5%8E%86%E7%9B%AE%E5%BD%95%E5%92%8C%E6%96%87%E4%BB%B6/</id>
    <published>2018-05-18T02:28:15.000Z</published>
    <updated>2018-05-21T17:22:58.000Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/thanks_for_watching.jpg"></p><p><escape><span id="more"></span></escape></p><p>最近翻移动硬盘，发现自己还短暂的写过两个月的perl语言，盘中赫然躺着一些perl脚本，其中一个便是实现的遍历目录及其包含的文件的脚本。<br>该功能无非就是利用递归来写代码，这里想用perl、python、shell和C语言分别对其进行编写，聊发少年狂而已。</p><h1 id="1、程序列表"><a href="#1、程序列表" class="headerlink" title="1、程序列表"></a>1、程序列表</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost script]# ls -tlr</span><br><span class="line">total 28</span><br><span class="line">-rwxr--r--. 1 root root  276 May 17 19:16 shell_find.sh</span><br><span class="line">-rwxr--r--. 1 root root  444 May 17 19:17 python_find.py</span><br><span class="line">-rwxr--r--. 1 root root  782 May 17 19:18 perl_find.sh</span><br><span class="line">-rw-r--r--. 1 root root 1184 May 17 19:36 C_Find.c</span><br><span class="line">-rwxr-xr-x. 1 root root 9048 May 17 19:37 C_Find</span><br><span class="line">[root@localhost script]# </span><br></pre></td></tr></table></figure><h2 id="1-1-perl"><a href="#1-1-perl" class="headerlink" title="1.1 perl"></a>1.1 perl</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">#! /usr/bin/perl</span><br><span class="line"></span><br><span class="line">use strict;</span><br><span class="line"></span><br><span class="line">my @filelist;</span><br><span class="line">my $dir = &quot;../python&quot;;</span><br><span class="line"></span><br><span class="line">push(@filelist,&amp;findfile($dir));</span><br><span class="line">print join(&quot;\n&quot;,@filelist);</span><br><span class="line">print &quot;\n&quot;;</span><br><span class="line"></span><br><span class="line">sub findfile&#123;</span><br><span class="line">        my @filelist;</span><br><span class="line">        my $dir = $_[0];</span><br><span class="line">        opendir(DIR,$dir);</span><br><span class="line">        my @temp = grep(!/^\.\.?$/,readdir(DIR));</span><br><span class="line">        close(DIR);</span><br><span class="line">        my $count = @temp;</span><br><span class="line">        my $i; </span><br><span class="line">        my $tmpdir;</span><br><span class="line">        for($i = 0; $i &lt; $count; $i++)&#123;</span><br><span class="line">                $tmpdir = (); </span><br><span class="line">                $tmpdir = &quot;$dir/$temp[$i]&quot;;</span><br><span class="line">                if(-d &quot;$tmpdir&quot;)&#123;</span><br><span class="line">                        push(@filelist,$tmpdir);                                                                                                                                             </span><br><span class="line">                        push(@filelist,&amp;findfile(&quot;$tmpdir&quot;));</span><br><span class="line">                &#125;   </span><br><span class="line">                else &#123;</span><br><span class="line">                        push(@filelist,$tmpdir);</span><br><span class="line">                &#125;   </span><br><span class="line">        &#125;   </span><br><span class="line">        return @filelist;   </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="1-2-python"><a href="#1-2-python" class="headerlink" title="1.2 python"></a>1.2 python</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">#! /usr/bin/python3</span><br><span class="line"># coding=utf-8</span><br><span class="line"></span><br><span class="line">import os</span><br><span class="line">basedir = &#x27;../python&#x27;</span><br><span class="line">filelists = []</span><br><span class="line"></span><br><span class="line">def find(basedir):</span><br><span class="line">    global filelists</span><br><span class="line">    for parent,dirnames,filenames in os.walk(basedir):</span><br><span class="line">        for dirname in dirnames:</span><br><span class="line">            filelists.append(os.path.join(parent,dirname))                                                                                                                                   </span><br><span class="line">        for filename in filenames:</span><br><span class="line">            filelists.append(os.path.join(parent,filename))</span><br><span class="line"></span><br><span class="line">if __name__ == &#x27;__main__&#x27;:</span><br><span class="line">    find(basedir)</span><br><span class="line">    print(&#x27;\n&#x27;.join(filelists))</span><br></pre></td></tr></table></figure><h2 id="1-3-shell"><a href="#1-3-shell" class="headerlink" title="1.3 shell"></a>1.3 shell</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">#! /usr/bin/bash</span><br><span class="line"></span><br><span class="line">set -o nounset</span><br><span class="line">set -o errexit</span><br><span class="line"></span><br><span class="line">function find()&#123;</span><br><span class="line">    for file in `ls $1`</span><br><span class="line">    do  </span><br><span class="line">        if [ -d $1&quot;/&quot;$file ]</span><br><span class="line">        then</span><br><span class="line">            echo $1&quot;/&quot;$file                                                                                                                                                                  </span><br><span class="line">            find $1&quot;/&quot;$file</span><br><span class="line">        else</span><br><span class="line">            echo $1&quot;/&quot;$file</span><br><span class="line">        fi  </span><br><span class="line">    done</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">find &quot;../python&quot;</span><br></pre></td></tr></table></figure><h2 id="1-4-C"><a href="#1-4-C" class="headerlink" title="1.4 C"></a>1.4 C</h2><p>源代码：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line">/* list dir and files through C */                                                                                                                                                           </span><br><span class="line"></span><br><span class="line">#include &lt;stdio.h&gt;</span><br><span class="line">#include &lt;stdlib.h&gt;</span><br><span class="line">#include &lt;string.h&gt;</span><br><span class="line">#include &lt;unistd.h&gt;</span><br><span class="line"></span><br><span class="line">#include &lt;dirent.h&gt;</span><br><span class="line">#include &lt;sys/stat.h&gt;</span><br><span class="line">#include &lt;sys/types.h&gt;</span><br><span class="line"></span><br><span class="line">#define MAX_PATH_LENGTH 512 </span><br><span class="line"></span><br><span class="line">int find(char *path)</span><br><span class="line">&#123;</span><br><span class="line">    DIR *ptr_dir;</span><br><span class="line">    struct dirent *dir_entry;</span><br><span class="line">    </span><br><span class="line">    int i = 0;</span><br><span class="line">    char *child_path;</span><br><span class="line"></span><br><span class="line">    child_path = (char*)malloc(sizeof(char)*MAX_PATH_LENGTH);</span><br><span class="line">    if(child_path == NULL)&#123;</span><br><span class="line">        printf(&quot;malloc child_path occurs errors.\n&quot;);</span><br><span class="line">        exit(1);</span><br><span class="line">    &#125;   </span><br><span class="line">    </span><br><span class="line">    memset(child_path,0x0,sizeof(char)*MAX_PATH_LENGTH);</span><br><span class="line"></span><br><span class="line">    ptr_dir = opendir(path);</span><br><span class="line">    while(( dir_entry = readdir(ptr_dir) ) != NULL)&#123;</span><br><span class="line">        if(dir_entry-&gt;d_type &amp; DT_DIR)&#123;</span><br><span class="line">            if(strcmp(dir_entry-&gt;d_name,&quot;.&quot;) == 0 ||  </span><br><span class="line">                    strcmp(dir_entry-&gt;d_name,&quot;..&quot;) == 0)&#123; </span><br><span class="line">                continue;</span><br><span class="line">            &#125;   </span><br><span class="line">            sprintf(child_path,&quot;%s/%s&quot;,path,dir_entry-&gt;d_name);</span><br><span class="line">            printf(&quot;%s\n&quot;,child_path);</span><br><span class="line">    </span><br><span class="line">            find(child_path);</span><br><span class="line">        &#125; else &#123;</span><br><span class="line">            printf(&quot;%s/%s\n&quot;,path,dir_entry-&gt;d_name);</span><br><span class="line">        &#125;   </span><br><span class="line">    &#125;   </span><br><span class="line">    </span><br><span class="line">    free(child_path);</span><br><span class="line">    child_path = NULL;</span><br><span class="line"></span><br><span class="line">    return 0;</span><br><span class="line">&#125;</span><br><span class="line">int main()</span><br><span class="line">&#123;</span><br><span class="line">    find(&quot;../python&quot;);</span><br><span class="line"></span><br><span class="line">    return 0;</span><br><span class="line">&#125;  </span><br></pre></td></tr></table></figure><p>编译：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -o C_Find C_Find.c</span><br></pre></td></tr></table></figure><h1 id="2、执行结果"><a href="#2、执行结果" class="headerlink" title="2、执行结果"></a>2、执行结果</h1><p>上述代码执行结果一致，输出文件列表的默认排序或有差别。<br>以shell脚本的执行结果为例，输出如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost script]# ./shell_find.sh </span><br><span class="line">../python/countCodeLine2.py</span><br><span class="line">../python/countCodeLine.py</span><br><span class="line">../python/countCodeLine.py_ori</span><br><span class="line">../python/Django</span><br><span class="line">../python/How_to_be_pythonic</span><br><span class="line">../python/How_to_be_pythonic/add.c</span><br><span class="line">../python/How_to_be_pythonic/adder.so</span><br><span class="line">../python/How_to_be_pythonic/app_decrator.py</span><br><span class="line">../python/How_to_be_pythonic/cpython_api.py</span><br><span class="line">../python/How_to_be_pythonic/cpython_ctype.py</span><br><span class="line">../python/How_to_be_pythonic/cpython_SWIG.py</span><br><span class="line">../python/How_to_be_pythonic/debug.txt</span><br><span class="line">../python/How_to_be_pythonic/decrator.py</span><br><span class="line">../python/How_to_be_pythonic/def__.py</span><br><span class="line">../python/How_to_be_pythonic/enumerate.py</span><br><span class="line">../python/How_to_be_pythonic/exception.py</span><br><span class="line">../python/How_to_be_pythonic/forelse.py</span><br><span class="line">../python/How_to_be_pythonic/funccode1.py</span><br><span class="line">../python/How_to_be_pythonic/Generators.py</span><br><span class="line">../python/How_to_be_pythonic/kw-args.py</span><br><span class="line">../python/How_to_be_pythonic/out.log</span><br><span class="line">../python/How_to_be_pythonic/pprint.py</span><br><span class="line">../python/How_to_be_pythonic/set.py</span><br><span class="line">../python/How_to_be_pythonic/test3.py</span><br><span class="line">../python/How_to_be_pythonic/test.py</span><br><span class="line">[root@localhost script]# </span><br></pre></td></tr></table></figure><h1 id="3、后记"><a href="#3、后记" class="headerlink" title="3、后记"></a>3、后记</h1><ol><li>C语言的实现方法中，有关dirent、stat等结构体含义的描述，可参见：<br> <a href="http://www.360doc.com/content/15/0701/10/5470123_481878714.shtml">http://www.360doc.com/content/15/0701/10/5470123_481878714.shtml</a></li><li>代码中输出的是目录及文件，可调整。</li><li>对列出的文件可做进一步的条件筛选，如后缀判断等。</li><li>可比较时间，可优化。</li><li>本文原作者:不出名的刀客，转载请一同转发本文链接。</li><li>第一次网上写技术文，文有不对之处，欢迎指正。</li><li>另，小白正在学习python，欢迎大神留言指教。</li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;img src=&quot;/images/thanks_for_watching.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;escape&gt;</summary>
    
    
    
    <category term="开发经验" scheme="http://xiejing2014.github.io/categories/%E5%BC%80%E5%8F%91%E7%BB%8F%E9%AA%8C/"/>
    
    
    <category term="perl" scheme="http://xiejing2014.github.io/tags/perl/"/>
    
    <category term="python" scheme="http://xiejing2014.github.io/tags/python/"/>
    
    <category term="shell" scheme="http://xiejing2014.github.io/tags/shell/"/>
    
    <category term="C/C++" scheme="http://xiejing2014.github.io/tags/C-C/"/>
    
  </entry>
  
</feed>
