如何把 pgrep 输出结果中需要用单引号包起来的参数包起来? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
wniming
V2EX    Linux

如何把 pgrep 输出结果中需要用单引号包起来的参数包起来?

  •  
  •   wniming 150 天前 1980 次点击
    这是一个创建于 150 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如有如下 qemu 的命令行:

    qemu-system-x86_64 \ -machine q35,accel=kvm \ -cpu host \ -m 1G \ -kernel /home/d/kernel/kernel \ -initrd /home/d/rd/initramfs.cpio.gz \ -append 'cOnsole=ttyS0 test="11 22"' \ -netdev '{"type":"tap","vhost":true,"ifname":"eth_0","id":"hostnet0","script":"","downscript":""}' \ -device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:c0:45:c7"}' \ -nographic 

    上述命令的参数的格式是有效的,但是如果命令执行后通过 pgrep 查询命令行字符串,查询出的结果会把单引号去掉:

    d@develop:~$ pgrep -af qemu-system-x86_64 | perl -0pe 's/ -/ \\\n-/g' 19754 qemu-system-x86_64 \ -machine q35,accel=kvm \ -cpu host \ -m 1G \ -kernel /home/d/kernel/kernel \ -initrd /home/d/rd/initramfs.cpio.gz \ -append cOnsole=ttyS0 test="11 22" \ -netdev {"type":"tap","vhost":true,"ifname":"eth_0","id":"hostnet0","script":"","downscript":""} \ -device {"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:c0:45:c7"} \ -nographic 

    去掉单引号的命令无法直接放到 shell 里去执行,我想找到一个通用的办法(不要仅限于 qemu 的参数)把 pgrpe 输出的命令行字符串中需要用单引号包起来的参数用单引号包起来,使其结果和最初执行的命令行字符串完全一样,问了 ai ,ai 解决不了,再次在这里求助 v 友。

    第 1 条附言    150 天前

    #7 楼给出的方法管用,这里备份一下:

    #!/usr/bin/env python3 import sys import shlex def get_cmdline(pid): with open(f"/proc/{pid}/cmdline") as f: raw = f.read() parts = raw.strip("\0").split("\0") return shlex.join(parts) def main(): if len(sys.argv) != 2: print(f"Usage: {sys.argv[0]} <pid>", file=sys.stderr) sys.exit(1) pid = sys.argv[1] print(get_cmdline(pid)) if __name__ == "__main__": main() 
    11 条回复    2025-07-28 09:44:20 +08:00
    julyclyde
        1
    julyclyde  
       150 天前
    你去/proc/pid/cmdline 里边按照\0 重新组装一下命令行吧
    wniming
        2
    wniming  
    OP
       150 天前
    @julyclyde 能具体一点吗?我想当伸手党。。。。

    我自己简单研究了一下,你说的这种方法和 pgrep 没有什么区别:

    d@develop:~$ cat /proc/19754/cmdline | xargs -0 echo | perl -0pe 's/ -/ \\\n-/g'
    qemu-system-x86_64 \
    -machine q35,accel=kvm \
    -cpu host \
    -m 1G \
    -kernel /home/d/kernel/kernel \
    -initrd /home/d/rd/initramfs.cpio.gz \
    -append cOnsole=ttyS0 test="11 22" \
    -netdev {"type":"tap","vhost":true,"ifname":"eth_0","id":"hostnet0","script":"","downscript":""} \
    -device {"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:c0:45:c7"} \
    -nographic
    julyclyde
        3
    julyclyde  
       150 天前
    @wniming 其实按说你可以无脑把里边每个字段都加上引号吧?

    你下一步打算怎么使用这个内容?
    billlee
        4
    billlee  
       150 天前
    别用 shell 了,用 python 调 os.execvp, 把参数用数组的形式传进去,就不需要引号和转义。
    wniming
        5
    wniming  
    OP
       150 天前
    @julyclyde #3 是的,最简单的方式就是每个选项和参数都用单引号包起来,但是这样不美观,我是想把命令行存到日志文件里,就像 libvirt 那样,libvirt 就把日志里的 qemu 命令行格式化成了我想要的效果:

    /usr/bin/qemu-system-x86_64 \
    -name guest=win11-23h2,debug-threads=on \
    -S \
    -object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-9-win11-23h2/master-key.aes"}' \
    -blockdev '{"driver":"file","filename":"/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
    -blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"qcow2","file":"libvirt-pflash0-storage","backing":null}' \
    -blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/win11-23h2_VARS.qcow2","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \
    -blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"qcow2","file":"libvirt-pflash1-storage","backing":null}' \
    -machine pc-q35-8.2,usb=off,vmport=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,hpet=off,acpi=on \
    -accel kvm \
    -cpu host,migratable=on,host-phys-bits=on,host-phys-bits-limit=39 \
    -m size=16777216k \
    -object '{"qom-type":"memory-backend-memfd","id":"pc.ram","hugetlb":true,"hugetlbsize":1073741824,"share":true,"x-use-canonical-path-for-ramblock-id":false,"prealloc":true,"size":17179869184}' \
    -overcommit mem-lock=off \
    -smp 8,sockets=1,dies=1,clusters=1,cores=8,threads=1 \
    -uuid a7849adb-a74b-4086-a0a6-738c5e689a8a \
    -no-user-config \
    -nodefaults \
    -chardev socket,id=charmonitor,fd=23,server=on,wait=off \
    -mon chardev=charmonitor,id=monitor,mode=control \
    -rtc base=utc,driftfix=slew \
    -global kvm-pit.lost_tick_policy=delay \
    -no-shutdown \
    -global ICH9-LPC.disable_s3=1 \
    -global ICH9-LPC.disable_s4=1 \
    -boot menu=on,strict=on \
    -device '{"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"}' \
    -device '{"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"}' \
    -device '{"driver":"pcie-root-port","port":18,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x2.0x2"}' \
    -device '{"driver":"pcie-root-port","port":19,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x2.0x3"}' \
    -device '{"driver":"pcie-root-port","port":20,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x4"}' \
    -device '{"driver":"pcie-root-port","port":21,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"}' \
    -device '{"driver":"pcie-root-port","port":22,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x2.0x6"}' \
    -device '{"driver":"pcie-root-port","port":23,"chassis":8,"id":"pci.8","bus":"pcie.0","addr":"0x2.0x7"}' \
    -device '{"driver":"pcie-root-port","port":24,"chassis":9,"id":"pci.9","bus":"pcie.0","multifunction":true,"addr":"0x3"}' \
    -device '{"driver":"pcie-root-port","port":25,"chassis":10,"id":"pci.10","bus":"pcie.0","addr":"0x3.0x1"}' \
    -device '{"driver":"pcie-root-port","port":26,"chassis":11,"id":"pci.11","bus":"pcie.0","addr":"0x3.0x2"}' \
    -device '{"driver":"pcie-root-port","port":27,"chassis":12,"id":"pci.12","bus":"pcie.0","addr":"0x3.0x3"}' \
    -device '{"driver":"pcie-root-port","port":28,"chassis":13,"id":"pci.13","bus":"pcie.0","addr":"0x3.0x4"}' \
    -device '{"driver":"pcie-root-port","port":29,"chassis":14,"id":"pci.14","bus":"pcie.0","addr":"0x3.0x5"}' \
    -device '{"driver":"pcie-root-port","port":8,"chassis":15,"id":"pci.15","bus":"pcie.0","addr":"0x1"}' \
    -device '{"driver":"pcie-pci-bridge","id":"pci.16","bus":"pci.12","addr":"0x0"}' \
    -device '{"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"}' \
    -device '{"driver":"virtio-scsi-pci","id":"scsi0","bus":"pci.7","addr":"0x0"}' \
    -device '{"driver":"virtio-serial-pci","id":"virtio-serial0","bus":"pci.3","addr":"0x0"}' \
    -blockdev '{"driver":"host_device","filename":"/dev/thin/win11_23h2","aio":"native","node-name":"libvirt-1-storage","read-only":false,"discard":"unmap","cache":{"direct":true,"no-flush":false}}' \
    -device '{"driver":"virtio-blk-pci","bus":"pci.4","addr":"0x0","drive":"libvirt-1-storage","id":"virtio-disk0","bootindex":1,"write-cache":"on"}' \
    -netdev '{"type":"tap","fd":"24","vhost":true,"vhostfd":"32","id":"hostnet0"}' \
    -device '{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:1a:14:2d","bus":"pci.1","addr":"0x0"}' \
    -netdev '{"type":"tap","fd":"33","vhost":true,"vhostfd":"34","id":"hostnet1"}' \
    -device '{"driver":"virtio-net-pci","netdev":"hostnet1","id":"net1","mac":"52:54:00:e1:84:76","bus":"pci.11","addr":"0x0"}' \
    -chardev spicevmc,id=charchannel0,name=vdagent \
    -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":2,"chardev":"charchannel0","id":"channel0","name":"com.redhat.spice.0"}' \
    -chardev socket,id=charchannel1,fd=22,server=on,wait=off \
    -device '{"driver":"virtserialport","bus":"virtio-serial0.0","nr":1,"chardev":"charchannel1","id":"channel1","name":"org.qemu.guest_agent.0"}' \
    -audiodev '{"id":"audio1","driver":"spice"}' \
    -spice port=5900,addr=0.0.0.0,disable-ticketing=on,image-compression=off,seamless-migration=on \
    -global ICH9-LPC.noreboot=off \
    -watchdog-action reset \
    -chardev spicevmc,id=charredir0,name=usbredir \
    -device '{"driver":"usb-redir","chardev":"charredir0","id":"redir0","bus":"usb.0","port":"2"}' \
    -chardev spicevmc,id=charredir1,name=usbredir \
    -device '{"driver":"usb-redir","chardev":"charredir1","id":"redir1","bus":"usb.0","port":"3"}' \
    -chardev spicevmc,id=charredir2,name=usbredir \
    -device '{"driver":"usb-redir","chardev":"charredir2","id":"redir2","bus":"usb.0","port":"4"}' \
    -chardev spicevmc,id=charredir3,name=usbredir \
    -device '{"driver":"usb-redir","chardev":"charredir3","id":"redir3","bus":"usb.0","port":"5"}' \
    -device '{"driver":"vfio-pci","host":"0000:08:00.0","id":"hostdev0","bus":"pci.5","addr":"0x0","romfile":"/home/d/.local/share/libvirt/rom/Navi_23.rom"}' \
    -device '{"driver":"vfio-pci","host":"0000:08:00.1","id":"hostdev1","bus":"pci.8","addr":"0x0"}' \
    -object '{"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"}' \
    -device '{"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"}' \
    -device '{"driver":"usb-host","hostbus":1,"hostport":"7","bus":"usb.0"}' \
    -device '{"driver":"usb-host","hostbus":1,"hostport":"11","bus":"usb.0"}' \
    -device '{"driver":"usb-host","hostbus":1,"hostport":"10.4","bus":"usb.0"}' \
    -device '{"driver":"usb-host","hostbus":1,"hostport":"10.2","bus":"usb.0"}' \
    -sandbox off \
    -msg timestamp=on

    只把需要用单引号包起来的参数用单引包起来。
    wniming
        6
    wniming  
    OP
       150 天前
    @billlee 我是想把 qemu 的命令行保存到文件里
    sunfkny
        7
    sunfkny  
       150 天前   1
    https://gist.github.com/sunfkny/90f4a99c7444a840bb5f651c758a38f3
    还得是 python, 核心就是\0 分割 cmdline 之后 shlex.join
    wniming
        8
    wniming  
    OP
       150 天前
    @sunfkny 谢谢,完美解决
    billlee
        9
    billlee  
       150 天前
    @wniming 只用单引号包起来是不能处理所有情况的,因为参数里可能本身就有单引号。如果需求只是“保存”,那按照 /proc/$pid/cmdline 原样保存就行了。如果其实你需要的是转换成 shell 格式,那需要遍历每个参数,对参数做 shell escape
    guanzhangzhang
        10
    guanzhangzhang  
       150 天前
    xargs -0 /proc/<pid>/cmdline > result.txt
    guanzhangzhang
        11
    guanzhangzhang  
       150 天前
    @guanzhangzhang xargs -0 < /proc/<pid>/cmdline > result.txt
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3930 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 42ms UTC 05:12 PVG 13:12 LAX 21:12 JFK 00:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86