• Linux命令之xargs的分析及隐患


    写一个main.c:

    #include <stdio.h>

    int main(){

      printf("foo");

      printf("bar");

     return 0;

    }

    然后gcc编译为test.

    然后在工作目录下建立两个目录:foo,bar

    然后./test | xargs rm -rf

    其实以上命令是删除不掉foo和bar的。

    然后再来看以下

    写一个main.c:

    #include <stdio.h>

    int main(){

      printf("foo ");

      printf("bar ");

     return 0;

    }

    然后gcc编译为test.

    然后在工作目录下建立两个目录:foo,bar

    然后./test | xargs rm -rf

    其实以上命令是能把foo bar删除了的。

    然后再修改main.c

    #include <stdio.h>

    int main(){

      printf("foo bar ");

     return 0;

    }

    以上的修改是也能删除foo和bar

    然后再修改main.c

    #include <stdio.h>

    int main(){

      printf("foo  bar");

     return 0;

    }

    以上的修改是也能删除foo和bar

    所以总结:

     xargs是把整个输入流中的字符串遇到空格和换行符' '就截断为参数字符串(比如"foo bar"会被截断为两个字符串"foo"和"bar")传递给rm的,之前的foo和bar的输出没有换行符和空格,输出来就是“foobar”,由于工作目录没有建立foobar目录,当然就删除不掉了,所以也删不掉foo,bar目录。这样很显然是违背用户意愿了,如果工作目录下真存在foobar目录呢?万一这个目录很重要呢?那就悲剧了。

    真相如下:

    如果这回test是输出"foo bar"

    有xargs的:(这个很明显能看到xargs的作用了)

    ./test | xargs strace rm -rf
    execve("/bin/rm", ["rm", "-rf", "foo", "bar"], [/* 50 vars */]) = 0
    brk(0)                                  = 0x17fc000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e5fc7b000
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=78756, ...}) = 0
    mmap(NULL, 78756, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6e5fc67000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "177ELF2113>1240302"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, ...}) = 0
    mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6e5f69b000
    mprotect(0x7f6e5f850000, 2097152, PROT_NONE) = 0
    mmap(0x7f6e5fa50000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f6e5fa50000
    mmap(0x7f6e5fa56000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6e5fa56000
    close(3)                                = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e5fc66000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e5fc65000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6e5fc64000
    arch_prctl(ARCH_SET_FS, 0x7f6e5fc65700) = 0
    mprotect(0x7f6e5fa50000, 16384, PROT_READ) = 0
    mprotect(0x60c000, 4096, PROT_READ)     = 0
    mprotect(0x7f6e5fc7d000, 4096, PROT_READ) = 0
    munmap(0x7f6e5fc67000, 78756)           = 0
    brk(0)                                  = 0x17fc000
    brk(0x181d000)                          = 0x181d000
    open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=93101680, ...}) = 0
    mmap(NULL, 93101680, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6e59dd1000
    close(3)                                = 0
    ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffd51c9478) = -1 ENOTTY (Inappropriate ioctl for device)
    lstat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
    newfstatat(AT_FDCWD, "foo", {st_mode=S_IFDIR|0775, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
    openat(AT_FDCWD, "foo", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
    fcntl(3, F_GETFD)                       = 0
    fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
    fstat(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
    fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
    fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
    fcntl(3, F_DUPFD, 3)                    = 4
    fcntl(4, F_GETFD)                       = 0
    fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
    getdents(3, /* 2 entries */, 32768)     = 48
    getdents(3, /* 0 entries */, 32768)     = 0
    close(3)                                = 0
    unlinkat(AT_FDCWD, "foo", AT_REMOVEDIR) = 0
    close(4)                                = 0
    newfstatat(AT_FDCWD, "bar", {st_mode=S_IFDIR|0775, st_size=4096, ...}, AT_SYMLINK_NOFOLLOW) = 0
    openat(AT_FDCWD, "bar", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_DIRECTORY|O_NOFOLLOW) = 3
    fcntl(3, F_GETFD)                       = 0
    fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
    fstat(3, {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
    fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
    fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
    fcntl(3, F_DUPFD, 3)                    = 4
    fcntl(4, F_GETFD)                       = 0
    fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
    getdents(3, /* 2 entries */, 32768)     = 48
    getdents(3, /* 0 entries */, 32768)     = 0
    close(3)                                = 0
    unlinkat(AT_FDCWD, "bar", AT_REMOVEDIR) = 0
    close(4)                                = 0
    lseek(0, 0, SEEK_CUR)                   = 0
    close(0)                                = 0
    close(1)                                = 0
    close(2)                                = 0
    exit_group(0)                           = ?

    没有xargs的:(由以下分析,很显然连“foo bar”这个参数都没有传递进去)

    a@a:~/Downloads$ ./test |  strace rm -rf
    execve("/bin/rm", ["rm", "-rf"], [/* 50 vars */]) = 0
    brk(0)                                  = 0x17a9000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1bdbc08000
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=78756, ...}) = 0
    mmap(NULL, 78756, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1bdbbf4000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
    read(3, "177ELF2113>1240302"..., 832) = 832
    fstat(3, {st_mode=S_IFREG|0755, st_size=1815224, ...}) = 0
    mmap(NULL, 3929304, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f1bdb628000
    mprotect(0x7f1bdb7dd000, 2097152, PROT_NONE) = 0
    mmap(0x7f1bdb9dd000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f1bdb9dd000
    mmap(0x7f1bdb9e3000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f1bdb9e3000
    close(3)                                = 0
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1bdbbf3000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1bdbbf2000
    mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1bdbbf1000
    arch_prctl(ARCH_SET_FS, 0x7f1bdbbf2700) = 0
    mprotect(0x7f1bdb9dd000, 16384, PROT_READ) = 0
    mprotect(0x60c000, 4096, PROT_READ)     = 0
    mprotect(0x7f1bdbc0a000, 4096, PROT_READ) = 0
    munmap(0x7f1bdbbf4000, 78756)           = 0
    brk(0)                                  = 0x17a9000
    brk(0x17ca000)                          = 0x17ca000
    open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
    fstat(3, {st_mode=S_IFREG|0644, st_size=93101680, ...}) = 0
    mmap(NULL, 93101680, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f1bd5d5e000
    close(3)                                = 0
    ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffa591a788) = -1 ENOTTY (Inappropriate ioctl for device)
    lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
    close(0)                                = 0
    close(1)                                = 0
    close(2)                                = 0
    exit_group(0)                           = ?

  • 相关阅读:
    字符串比较
    LOOP AT SCREEN
    Trunc的日期用法
    【ABAP】SELECT-ENDSELECT尽量不要用
    【转】Abap For all entries in 使用
    01如何创建sequence:
    abap --MOVE-CORRESPONDING
    Abap 常用变量
    StringBuffer的用法
    Spring事务的传播方式
  • 原文地址:https://www.cnblogs.com/foohack/p/4028977.html
Copyright © 2020-2023  润新知