热点

生产环境CPU狂飙900%,到底该如何处理?

字号+作者:益华科技来源:IT科技类资讯2025-11-05 10:20:13我要评论(0)

首先,说明一下问题:CPU飙升200% 以上是生产环境非常容易发生的场景。场景:1:MySQL进程飙升900%大家在使用MySQL过程,想必都有遇到过CPU突然过高,或者达到200%以上的情况。数据库

首先,生产说明一下问题:CPU飙升200% 以上是环境何处生产环境非常容易发生的场景。

场景:1:MySQL进程飙升900%

大家在使用MySQL过程,底该想必都有遇到过CPU突然过高,生产或者达到200%以上的环境何处情况。

数据库执行查询或数据修改操作时,底该系统需要消耗大量的生产CPU资源维护从存储系统、内存数据中的环境何处一致性。

并发量大并且大量SQL性能低的底该情况下,比如字段是生产没有建立索引,则会导致快速CPU飙升,环境何处如果还开启了慢日志记录,底该会导致性能更加恶化。生产生产上有MYSQL 飙升900% 的环境何处恶劣情况。

场景2:Java进程飙升900%

一般来说Java 进程不做大量 CPU 运算,底该正常情况下,CPU 应该在 100~200% 之间,但是,一旦高并发场景,要么走到了死循环,要么就是在做大量的 GC,  容易出现这种 CPU 飙升的情况,CPU飙升900%,站群服务器完全有可能的。

其他场景:其他的类似进程飙升900%的场景

比如Redis、Nginx等等。

大家介绍场景的时候,就说自己主要涉及了两个场景, Java进程飙升900%、MySQL进程飙升900%两种场景,其实,这两个场景就足够讲半天了, 其他的,使用规避技巧规避一下就行。

场景一:MySQL进程CPU飙升到900%,怎么处理?

定位过程

使用top 命令观察,确定是mysqld导致还是其他原因。如果是mysqld导致的,show processlist,查看session情况,确定是不是有消耗资源的sql在运行。找出消耗高的 sql,IT技术网看看执行计划是否准确, index 是否缺失,或者实在是数据量太大造成。

处理过程

kill 掉这些线程(同时观察 cpu 使用率是否下降), 一般来说,肯定要 kill 掉这些线程(同时观察 cpu 使用率是否下降),等进行相应的调整(比如说加索引、改 sql、改内存参数)之后,再重新跑这些 SQL。进行相应的调整(比如说加索引、改 sql、改内存参数)index 是否缺失,如果是,则  建立索引。也有可能是每个 sql 消耗资源并不多,但是突然之间,有大量的  session 连进来导致 cpu 飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,云服务器提供商比如说限制连接数等;优化的过程,往往不是一步完成的,而是一步一步,执行一项优化措辞,再观察,再优化。

场景1的真实案例:MySQL数据库优化的真实案例

以下案例,来自互联网。大家参考一下,准备一个自己的案例。

本问题亲身经历过。

之前开发同事编写的SQL语句,就导致过线上CPU过高,MySQL的CPU使用率达到900%+,通过优化最后降低到70%~80%。下面说说个人在这个过程中的排查思路。

首先,我们要对问题定位而不是盲目的开启什么 慢日志,在并发量大并且大量SQL性能低的情况下,开启慢日志无意是将MySQL推向崩溃的边缘。

当时遇到这个情况,分析了当前的数据量、索引情况、缓存使用情况。目测数据量不大,也就几百万条而已。接下来就去定位索引、缓存问题。

1、经过询问,发现很多查询都是走MySQL,没有用到缓存。

2、既然没有用到缓存,则是大量请求全部查询MySQL导致。通过下面的命令查看:

复制show processlist;1.

发现类似很多相同的SQL语句,一直处于query状态中。

复制select id form user where user_code = xxxxx;1.

初步分析可能是 user_code 字段没有索引导致。接着查询user表的索引情况:

复制show index form user;1.

发现这个字段是没有建立索引。增加索引之后,该条SQL查询能够正常执行。

3、没隔一会,又发生大量的请求超时问题。接着进行分析,发现是开启了 慢日志查询。大量的SQL查询语句超过慢日志设置的阀值,于是将慢日志关闭之后,速度瞬间提升。CPU的使用率基本保持在300%左右。但还不是理想状态。

4、紧接着将部分实时查询数据的SQL语句,都通过缓存(redis)读写实现。观察一段时间后,基本维持在了70%~80%。

总结:其实本次事故的解决很简单,就是添加索引与缓存结合使用。

不推荐在这种CPU使用过高的情况下进行慢日志的开启。因为大量的请求,如果真是慢日志问题会发生日志磁盘写入,性能贼低。直接通过MySQL show processlist命令查看,基本能清晰的定位出部分查询问题严重的SQL语句,在针对该SQL语句进行分析。一般可能就是索引、锁、查询大量字段、大表等问题导致。再则一定要使用缓存系统,降低对MySQL的查询频次。对于内存调优,也是一种解决方案。

场景2展开:Java进程CPU飙升到900%,怎么处理?

定位过程:

CPU飙升问题定位的一般步骤是:

首先通过top指令查看当前占用CPU较高的进程PID;查看当前进程消耗资源的线程PID:top -Hp PID通过print命令将线程PID转为16进制,根据该16进制值去打印的堆栈日志内查询,查看该线程所驻留的方法位置。通过jstack命令,查看栈信息,定位到线程对应的具体代码。分析代码解决问题。

处理过程:

1、如果是空循环,或者空自旋。

处理方式:可以使用Thread.sleep或者加锁,让线程适当的阻塞。

2、在循环的代码逻辑中,创建大量的新对象导致频繁GC。比如,从mysql查出了大量的数据,比如100W以上等等。

处理方式:可以减少对象的创建数量,或者,可以考虑使用 对象池。

3、其他的一些造成CPU飙升的场景,比如  selector空轮训导致CPU飙升 。

处理方式:参考Netty源码,无效的事件查询到了一定的次数,进行 selector 重建。

Java的CPU 飙升700%优化的真实案例

最近负责的一个项目上线,运行一段时间后发现对应的进程竟然占用了700%的CPU,导致公司的物理服务器都不堪重负,频繁宕机。

那么,针对这类java进程CPU飙升的问题,我们一般要怎么去定位解决呢?

采用top命令定位进程

登录服务器,执行top命令,查看CPU占用情况,找到进程的pid

复制top1.

图片

很容易发现,PID为29706的java进程的CPU飙升到700%多,且一直降不下来,很显然出现了问题。

使用top -Hp命令定位线程

使用 top -Hp命令(为Java进程的id号)查看该Java进程内所有线程的资源占用情况(按shft+p按照cpu占用进行排序,按shift+m按照内存占用进行排序)

此处按照cpu排序:

复制top -Hp 236021.

图片

很容易发现,多个线程的CPU占用达到了90%多。我们挑选线程号为30309的线程继续分析。

使用jstack命令定位代码

1.线程号转换5为16进制

printf “%x\n” 命令(tid指线程的id号)将以上10进制的线程号转换为16进制:

复制printf "%x\n" 303091.

图片

转换后的结果分别为7665,由于导出的线程快照中线程的nid是16进制的,而16进制以0x开头,所以对应的16进制的线程号nid为0x7665

2.采用jstack命令导出线程快照

通过使用dk自带命令jstack获取该java进程的线程快照并输入到文件中:

复制jstack -l 进程ID > ./jstack_result.txt1.

命令(为Java进程的id号)来获取线程快照结果并输入到指定文件。

复制jstack -l 29706 > ./jstack_result.txt1. 3.根据线程号定位具体代码

在jstack_result.txt 文件中根据线程好nid搜索对应的线程描述。

复制cat jstack_result.txt |grep -A 100 76651.

图片

根据搜索结果,判断应该是ImageConverter.run()方法中的代码出现问题。

当然,这里也可以直接采用。

复制jstack <pid> |grep -A 200 <nid>1.

来定位具体代码:

复制$jstack 44529 |grep -A 200 ae24 "System Clock" #28 daemon prio=5 os_prio=0 tid=0x00007efc19e8e800 nid=0xae24 waiting on condition [0x00007efbe0d91000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at java.lang.Thread.sleep(Thread.java:340) at java.util.concurrentC.TimeUnit.sleep(TimeUnit.java:386) at com.*.order.Controller.OrderController.detail(OrderController.java:37) //业务代码阻塞点1.2.3.4.5.6.7.

分析代码解决问题

下面是ImageConverter.run()方法中的部分核心代码。

逻辑说明:

复制//存储minicap的socket连接返回的数据 (改用消息队列存储读到的流数据) ,设置阻塞队列长度,防止出现内存溢出 //全局变量 private BlockingQueue<byte[]> dataQueue = new LinkedBlockingQueue<byte[]>(100000); //消费线程 @Override public void run() { //long start = System.currentTimeMillis(); while (isRunning) { //分析这里从LinkedBlockingQueue if (dataQueue.isEmpty()) { continue; } byte[] buffer = device.getMinicap().dataQueue.poll(); int len = buffer.length; }1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.

在while循环中,不断读取堵塞队列dataQueue中的数据,如果数据为空,则执行continue进行下一次循环。

如果不为空,则通过poll()方法读取数据,做相关逻辑处理。

初看这段代码好像每什么问题,但是如果dataQueue对象长期为空的话,这里就会一直空循环,导致CPU飙升。

那么如果解决呢?

分析LinkedBlockingQueue阻塞队列的API发现:

复制//取出队列中的头部元素,如果队列为空则调用此方法的线程被阻塞等待,直到有元素能被取出,如果等待过程被中断则抛出InterruptedException E take() throws InterruptedException; //取出队列中的头部元素,如果队列为空返回null E poll();1.2.3.4.

这两种取值的API,显然take方法更适合这里的场景。

代码修改为:

复制while (isRunning) { /* if (device.getMinicap().dataQueue.isEmpty()) { continue; }*/ byte[] buffer = new byte[0]; try { buffer = device.getMinicap().dataQueue.take(); } catch (InterruptedException e) { e.printStackTrace(); } …… }1.2.3.4.5.6.7.8.9.10.11.12.

重启项目后,测试发现项目运行稳定,对应项目进程的CPU消耗占比不到10%。

图片

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 技巧一、用命令行往文件的顶部添加文字每次我都会重新寻找这个命令的写法。下面就是如何使用sed往一个文件顶部添加一行的方法:复制代码代码如下: sed -i 1s/^/line to insertn/ path/to/file/you/want/to/change.txt技巧二、用命令行往配置文件里插入多行文本这种方法非常简单,很多人都知道,下面就是如何用命令行将(>>)多行文本插入一个文件中。这里使用的是“here document”语法,它能让你通过块文本符号来将段落插入文件中,通常用的符合是EOF(意思是 “End Of File”):复制代码代码如下:cat >>path/to/file/to/append-to.txt << EOF    export PATH=$HOME/jdk1.8.0_31/bin:$PATH    export JAVA_HOME=$HOME/jdk1.8.0_31/    EOF两个”EOF“之间的所有内容都会被添加到文件中。技巧三、用命令行递归方式全局搜索目录文件和替换假如你使用Eclipse,ItelliJ或其它IDE,这些工具的强大重构能力也许会让你轻松实现很多事情。但我估计很多时候你的开发环境中没有这样的集成工具。如何使用命令行对一个目录进行递归搜索和替换?别想Perl语言,你可以使用find and sed。复制代码代码如下:# OSX version    find . -type f -name *.txt -exec sed -i s/this/that/g {} +使用了一段时间后,我总结写出了一个函数,添加入了 .bashrc ,就像下面这样:复制代码代码如下:function sr {        find . -type f -exec sed -i s/$1/$2/g {} +}你可以像这样使用它:复制代码代码如下:sr wrong_word correct_word技巧四、用命令行在vim和Dropbox里开启一个临时文件我过去喜欢用Emacs里的scratch facility功能。也经常用Vim快速创建临时文件。下面这两个函数是使用openssl生成随机的字符串作为文件名:复制代码代码如下:function sc {      gvim ~/Dropbox/$(openssl rand -base64 10 | tr -dc a-zA-Z).txt    }         function scratch {      gvim ~/Dropbox/$(openssl rand -base64 10 | tr -dc a-zA-Z).txt    }在命令行窗口输入sc或scratch,一个新的gvim或macvim窗口就会弹出来,里面会加载一个随机文件名的临时文件。技巧五、用命令行下载文件,支持链接转向、HTTPS和安全加密等情况下载一个页面输出到终端,跟随链接转向,忽略安全异常:复制代码代码如下:curl -Lks 下载一个链接,跟随链接转向,忽略安全异常: [/code]curl -OLks 这里用了很多参数,你可以阅读这个简单的curl文档来了解它们。技巧六、Bashmarks你还没有在.bashrc里使用bashmarks吗?还在等待什么?它真的非常有用。它能帮你保持历史操作,跳回到你经常使用的目录。下面是我的配置文件里脚本,但我想上面的链接能提供你更多技巧:复制代码代码如下: # USAGE:    # s bookmarkname - saves the curr dir as bookmarkname    # g bookmarkname - jumps to the that bookmark    # g b[TAB] - tab completion is available    # l - list all bookmarks         # save current directory to bookmarks    touch ~/.sdirs    function s {      cat ~/.sdirs | grep -v export DIR_$1= >~/.sdirs1      mv ~/.sdirs1 ~/.sdirs      echo export DIR_$1=$PWD >>~/.sdirs    }         # jump to bookmark    function g {      source ~/.sdirs      cd $(eval $(echo echo $(echo $DIR_$1)))    }         # list bookmarks with dirnam    function l {      source ~/.sdirs      env | grep ^DIR_ | cut -c5- | grep ^.*=    }    # list bookmarks without dirname    function _l {      source ~/.sdirs      env | grep ^DIR_ | cut -c5- | grep ^.*= | cut -f1 -d =    }         # completion command for g    function _gcomp {        local curw        COMPREPLY=()        curw=${COMP_WORDS[COMP_CWORD]}        COMPREPLY=($(compgen -W `_l` -- $curw))        return 0    }         # bind completion command for g to _gcomp    complete -F _gcomp g技巧七、从格式化输出里提取一列(我最常使用的awk技巧)我几乎天天都会使用它。真的。经常会有一些输出,我只需要其中的第二列,或第三列,下面这个命令就能做到这些:复制代码代码如下:#Sample output of git status -s command:         $ git status -s         M .bashrc       .vim/bundle/extempore/         # Remove status code from git status and just get the file names    $ git status -s | awk {print $2}         .bashrc    .vim/bundle/extempore/为什么不写个函数,让我们随时都可以用呢?复制代码代码如下: function col {      awk -v col=$1 {print $col}    }这使得提取列非常容易,比如,你不想要第一列?简单:复制代码代码如下:$ git status -s | col 2         .bashrc    .vim/bundle/extempore/技巧八、忽略头x个词我对xargs很着迷,我感觉它就像一把快刀。但有时候用它获得的结果需要调整一下,也许需要取得一些值。例如,你想去掉下面文件影像里的一些信息:复制代码代码如下:function skip {        n=$(($1 + 1))        cut -d  -f$n-    }下面是如何使用它: 使用 docker images 得到下面的输出:复制代码代码如下:$ docker images         REPOSITORY                   TAG         IMAGE ID            CREATED             VIRTUAL SIZE                                 65a9e3ef7171        3 weeks ago         1.592 GB                                 7c01ca6c30f2        3 weeks ago         11.1 MB                                 9518620e6a0e        3 weeks ago         7.426 MB                                 430707ee7fe8        3 weeks ago         7.426 MB    boot2docker/boot2docker      latest      1dbd7ebffe31        3 weeks ago         1.592 GB    spaceghost/tinycore-x86_64   5.4         f47686df00df        7 weeks ago         11.1 MB    durdn/bithub                 latest      df1e39df8dbf        8 weeks ago         100.9 MB                                 c5e6cf38d985        8 weeks ago         100.9 MB    nginx                        latest      e426f6ef897e        12 weeks ago        100.2 MB    zoobab/tinycore-x64          latest      8cdd417ec611        8 months ago        7.426 MB    scratch                      latest      511136ea3c5a        20 months ago       0 B 使用上面的函数,你可以获取所有的IDs:复制代码代码如下:$ docker images | col 3         IMAGE    65a9e3ef7171    7c01ca6c30f2    9518620e6a0e    430707ee7fe8    1dbd7ebffe31    f47686df00df    df1e39df8dbf    c5e6cf38d985    e426f6ef897e    8cdd417ec611    511136ea3c5a 进一步处理:复制代码代码如下:docker images | col 3 | xargs         IMAGE 65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a 但前面的”IMAGE”字符我也想去掉:复制代码代码如下:docker images | col 3 | xargs | skip 1         65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a 完整的写下来就是这样:复制代码代码如下:docker rmi $(docker images | col 3 | xargs | skip 1)技巧九、创建自己的命令包在bash里,你可以很容易的创建自己的命令组件,你可以看一下下面我写的:复制代码代码如下: function dur {      case $1 in      clone|cl)        git clone git@bitbucket.org:nicolapaolucci/$2.git        ;;      move|mv)        git remote add bitbucket git@bitbucket.org:nicolapaolucci/$(basename $(pwd)).git        git push --all bitbucket        ;;      trackall|tr)        #track all remote branches of a project        for remote in $(git branch -r | grep -v master ); do git checkout --track $remote ; done        ;;      key|k)        #track all remote branches of a project        ssh $2 mkdir -p .ssh && cat >>.ssh/authorized_keys < ~/.ssh/id_rsa.pub        ;;      fun|f)        #list all custom bash functions defined        typeset -F | col 3 | grep -v _ | xargs | fold -sw 60        ;;      def|d)        #show definition of function $1        typeset -f $2        ;;      help|h|*)        echo [dur]dn shell automation tools        echo commands available:        echo  [cl]one, [mv|move]        echo  [f]fun lists all bash functions defined in .bashrc        echo  [def]  lists definition of function defined in .bashrc        echo  [k]ey  copies ssh key to target host        echo  [tr]ackall], [h]elp        ;;      esac    }通过上面的脚本,我可以将ssh key拷贝到任何网站服务器——只需要键入 dur key user@somehost.总结你可以试一下我的这个.bashrc文件,或你自己也可以写一个。

    技巧一、用命令行往文件的顶部添加文字每次我都会重新寻找这个命令的写法。下面就是如何使用sed往一个文件顶部添加一行的方法:复制代码代码如下: sed -i 1s/^/line to insertn/ path/to/file/you/want/to/change.txt技巧二、用命令行往配置文件里插入多行文本这种方法非常简单,很多人都知道,下面就是如何用命令行将(>>)多行文本插入一个文件中。这里使用的是“here document”语法,它能让你通过块文本符号来将段落插入文件中,通常用的符合是EOF(意思是 “End Of File”):复制代码代码如下:cat >>path/to/file/to/append-to.txt << EOF export PATH=$HOME/jdk1.8.0_31/bin:$PATH export JAVA_HOME=$HOME/jdk1.8.0_31/ EOF两个”EOF“之间的所有内容都会被添加到文件中。技巧三、用命令行递归方式全局搜索目录文件和替换假如你使用Eclipse,ItelliJ或其它IDE,这些工具的强大重构能力也许会让你轻松实现很多事情。但我估计很多时候你的开发环境中没有这样的集成工具。如何使用命令行对一个目录进行递归搜索和替换?别想Perl语言,你可以使用find and sed。复制代码代码如下:# OSX version find . -type f -name *.txt -exec sed -i s/this/that/g {} +使用了一段时间后,我总结写出了一个函数,添加入了 .bashrc ,就像下面这样:复制代码代码如下:function sr { find . -type f -exec sed -i s/$1/$2/g {} +}你可以像这样使用它:复制代码代码如下:sr wrong_word correct_word技巧四、用命令行在vim和Dropbox里开启一个临时文件我过去喜欢用Emacs里的scratch facility功能。也经常用Vim快速创建临时文件。下面这两个函数是使用openssl生成随机的字符串作为文件名:复制代码代码如下:function sc { gvim ~/Dropbox/$(openssl rand -base64 10 | tr -dc a-zA-Z).txt } function scratch { gvim ~/Dropbox/$(openssl rand -base64 10 | tr -dc a-zA-Z).txt }在命令行窗口输入sc或scratch,一个新的gvim或macvim窗口就会弹出来,里面会加载一个随机文件名的临时文件。技巧五、用命令行下载文件,支持链接转向、HTTPS和安全加密等情况下载一个页面输出到终端,跟随链接转向,忽略安全异常:复制代码代码如下:curl -Lks 下载一个链接,跟随链接转向,忽略安全异常: [/code]curl -OLks 这里用了很多参数,你可以阅读这个简单的curl文档来了解它们。技巧六、Bashmarks你还没有在.bashrc里使用bashmarks吗?还在等待什么?它真的非常有用。它能帮你保持历史操作,跳回到你经常使用的目录。下面是我的配置文件里脚本,但我想上面的链接能提供你更多技巧:复制代码代码如下: # USAGE: # s bookmarkname - saves the curr dir as bookmarkname # g bookmarkname - jumps to the that bookmark # g b[TAB] - tab completion is available # l - list all bookmarks # save current directory to bookmarks touch ~/.sdirs function s { cat ~/.sdirs | grep -v export DIR_$1= >~/.sdirs1 mv ~/.sdirs1 ~/.sdirs echo export DIR_$1=$PWD >>~/.sdirs } # jump to bookmark function g { source ~/.sdirs cd $(eval $(echo echo $(echo $DIR_$1))) } # list bookmarks with dirnam function l { source ~/.sdirs env | grep ^DIR_ | cut -c5- | grep ^.*= } # list bookmarks without dirname function _l { source ~/.sdirs env | grep ^DIR_ | cut -c5- | grep ^.*= | cut -f1 -d = } # completion command for g function _gcomp { local curw COMPREPLY=() curw=${COMP_WORDS[COMP_CWORD]} COMPREPLY=($(compgen -W `_l` -- $curw)) return 0 } # bind completion command for g to _gcomp complete -F _gcomp g技巧七、从格式化输出里提取一列(我最常使用的awk技巧)我几乎天天都会使用它。真的。经常会有一些输出,我只需要其中的第二列,或第三列,下面这个命令就能做到这些:复制代码代码如下:#Sample output of git status -s command: $ git status -s M .bashrc .vim/bundle/extempore/ # Remove status code from git status and just get the file names $ git status -s | awk {print $2} .bashrc .vim/bundle/extempore/为什么不写个函数,让我们随时都可以用呢?复制代码代码如下: function col { awk -v col=$1 {print $col} }这使得提取列非常容易,比如,你不想要第一列?简单:复制代码代码如下:$ git status -s | col 2 .bashrc .vim/bundle/extempore/技巧八、忽略头x个词我对xargs很着迷,我感觉它就像一把快刀。但有时候用它获得的结果需要调整一下,也许需要取得一些值。例如,你想去掉下面文件影像里的一些信息:复制代码代码如下:function skip { n=$(($1 + 1)) cut -d -f$n- }下面是如何使用它: 使用 docker images 得到下面的输出:复制代码代码如下:$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 65a9e3ef7171 3 weeks ago 1.592 GB 7c01ca6c30f2 3 weeks ago 11.1 MB 9518620e6a0e 3 weeks ago 7.426 MB 430707ee7fe8 3 weeks ago 7.426 MB boot2docker/boot2docker latest 1dbd7ebffe31 3 weeks ago 1.592 GB spaceghost/tinycore-x86_64 5.4 f47686df00df 7 weeks ago 11.1 MB durdn/bithub latest df1e39df8dbf 8 weeks ago 100.9 MB c5e6cf38d985 8 weeks ago 100.9 MB nginx latest e426f6ef897e 12 weeks ago 100.2 MB zoobab/tinycore-x64 latest 8cdd417ec611 8 months ago 7.426 MB scratch latest 511136ea3c5a 20 months ago 0 B 使用上面的函数,你可以获取所有的IDs:复制代码代码如下:$ docker images | col 3 IMAGE 65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a 进一步处理:复制代码代码如下:docker images | col 3 | xargs IMAGE 65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a 但前面的”IMAGE”字符我也想去掉:复制代码代码如下:docker images | col 3 | xargs | skip 1 65a9e3ef7171 7c01ca6c30f2 9518620e6a0e 430707ee7fe8 1dbd7ebffe31 f47686df00df df1e39df8dbf c5e6cf38d985 e426f6ef897e 8cdd417ec611 511136ea3c5a 完整的写下来就是这样:复制代码代码如下:docker rmi $(docker images | col 3 | xargs | skip 1)技巧九、创建自己的命令包在bash里,你可以很容易的创建自己的命令组件,你可以看一下下面我写的:复制代码代码如下: function dur { case $1 in clone|cl) git clone git@bitbucket.org:nicolapaolucci/$2.git ;; move|mv) git remote add bitbucket git@bitbucket.org:nicolapaolucci/$(basename $(pwd)).git git push --all bitbucket ;; trackall|tr) #track all remote branches of a project for remote in $(git branch -r | grep -v master ); do git checkout --track $remote ; done ;; key|k) #track all remote branches of a project ssh $2 mkdir -p .ssh && cat >>.ssh/authorized_keys < ~/.ssh/id_rsa.pub ;; fun|f) #list all custom bash functions defined typeset -F | col 3 | grep -v _ | xargs | fold -sw 60 ;; def|d) #show definition of function $1 typeset -f $2 ;; help|h|*) echo [dur]dn shell automation tools echo commands available: echo [cl]one, [mv|move] echo [f]fun lists all bash functions defined in .bashrc echo [def] lists definition of function defined in .bashrc echo [k]ey copies ssh key to target host echo [tr]ackall], [h]elp ;; esac }通过上面的脚本,我可以将ssh key拷贝到任何网站服务器——只需要键入 dur key user@somehost.总结你可以试一下我的这个.bashrc文件,或你自己也可以写一个。

    2025-11-05 10:17

  • 《以荣耀青春》(一部青春励志电视剧的感人故事)

    《以荣耀青春》(一部青春励志电视剧的感人故事)

    2025-11-05 09:25

  • 昂达V10手机的综合评测(一款性能出众、价格亲民的智能手机)

    昂达V10手机的综合评测(一款性能出众、价格亲民的智能手机)

    2025-11-05 09:12

  • 华为13寸笔记本的性能与实用性测评(华为13寸笔记本的配置、外观、性能表现和使用体验详解)

    华为13寸笔记本的性能与实用性测评(华为13寸笔记本的配置、外观、性能表现和使用体验详解)

    2025-11-05 08:30

网友点评