AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1280626
Accepted
martin_0004
martin_0004
Asked: 2020-10-07 12:02:32 +0800 CST2020-10-07 12:02:32 +0800 CST 2020-10-07 12:02:32 +0800 CST

使用 set -x 时提示字符串 PS4 复制自身

  • 772

我的操作系统:Ubuntu 18.04.5 LTS

我使用跟踪来对脚本进行故障排除。我注意到跟踪中的不同行为取决于我的设置方式。我想了解它为什么会这样。

我通常set -x在我的脚本中使用我需要进行跟踪的地方激活跟踪。然而,提示字符串 PS4(默认为“+”)似乎“重复”了自身。

在此处输入图像描述

如果我在shebang中主动追踪#!行,PS4 只打印一次。

在此处输入图像描述

同样,如果我bash直接调用运行我的脚本,并-x在命令行中指定,PS4 也只打印一次。

在此处输入图像描述

为什么set -x在第一个示例中表现不同?我想shell有一些基本的东西我没有在这里......

scripts bash prompt shebang
  • 1 1 个回答
  • 93 Views

1 个回答

  • Voted
  1. Best Answer
    steeldriver
    2020-10-07T16:45:51+08:002020-10-07T16:45:51+08:00

    这里的区别不在于您放置 的位置-x,而在于您是否指定要使用的 shell(通过 shebang 或通过使用 显式调用脚本bash -x)。

    根据man bash, PS4:

       PS4    The value of this parameter is expanded  as  with  PS1  and  the
              value  is  printed  before  each command bash displays during an
              execution trace.  The first character of PS4 is replicated  mul‐
              tiple  times, as necessary, to indicate multiple levels of indi‐
              rection.  The default is ``+ ''.
    

    但是,在这种情况下,“间接级别”的含义还没有公布。

    当您尝试在未指定要使用的解释器的情况下执行文本文件时,系统调用会execve失败并显示ENOEXEC (Exec format error). 接下来会发生什么取决于您尝试从中执行它的 shell,如下所述:

    • 哪个 shell 解释器运行没有 shebang 的脚本?

    特别是,如果调用 shell 是bash,则脚本似乎直接由调用 shell 执行:这似乎是手册中提到的“间接”:

    $ strace -e trace=%process -f bash -c 'echo "Starting $0"; ./hw_no_shebang; echo "Finished."'
    execve("/bin/bash", ["bash", "-c", "echo \"Starting $0\"; ./hw_no_sheb"...], 0x7ffd3dadbee8 /* 25 vars */) = 0
    arch_prctl(ARCH_SET_FS, 0x7f95fe939740) = 0
    Starting bash
    clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f95fe939a10) = 26515
    strace: Process 26515 attached
    [pid 26514] wait4(-1,  <unfinished ...>
    [pid 26515] execve("./hw_no_shebang", ["./hw_no_shebang"], 0x555e5058a4f0 /* 25 vars */) = -1 ENOEXEC (Exec format error)
    ++ echo Hello
    Hello
    ++ echo World
    World
    ++ set +x
    [pid 26515] exit_group(0)               = ?
    [pid 26515] +++ exited with 0 +++
    <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 26515
    --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26515, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
    wait4(-1, 0x7fffba5272d0, WNOHANG, NULL) = -1 ECHILD (No child processes)
    Finished.
    exit_group(0)                           = ?
    +++ exited with 0 +++
    

    请注意,bash -c此处的 strace 调用中的 代替了您的交互式 shell,而不是bash -x您在上一个示例中使用的那个。

    一旦我们添加一个shebang,例如:

    $ cat hw_shebang
    #!/bin/bash
    
    set -x
    echo "Hello"
    echo "World"
    set +x
    

    然后(无论是否-x使用set或其他方式调用),然后execve成功并且脚本在其自己的外壳中执行,没有“间接”:

    $ strace -e trace=%process -f bash -c 'echo "Starting $0"; ./hw_shebang; echo "Finished."'
    execve("/bin/bash", ["bash", "-c", "echo \"Starting $0\"; ./hw_shebang"...], 0x7ffccc0af338 /* 25 vars */) = 0
    arch_prctl(ARCH_SET_FS, 0x7f81b9ed2740) = 0
    Starting bash
    clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f81b9ed2a10) = 26553
    strace: Process 26553 attached
    [pid 26552] wait4(-1,  <unfinished ...>
    [pid 26553] execve("./hw_shebang", ["./hw_shebang"], 0x55879d9924f0 /* 25 vars */) = 0
    [pid 26553] arch_prctl(ARCH_SET_FS, 0x7fa55de83740) = 0
    + echo Hello
    Hello
    + echo World
    World
    + set +x
    [pid 26553] exit_group(0)               = ?
    [pid 26553] +++ exited with 0 +++
    <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 26553
    --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26553, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
    wait4(-1, 0x7ffda2983b10, WNOHANG, NULL) = -1 ECHILD (No child processes)
    Finished.
    exit_group(0)                           = ?
    +++ exited with 0 +++
    

    例如,如果您调用了 no-shebang 脚本dash,则行为会有所不同:在初始 failed 之后,execve它将执行脚本:execve/bin/sh

    $ strace -e trace=%process -f dash -c 'echo "Starting $0"; ./hw_no_shebang; echo "Finished."'
    execve("/bin/dash", ["dash", "-c", "echo \"Starting $0\"; ./hw_no_sheb"...], 0x7ffc283d8638 /* 25 vars */) = 0
    arch_prctl(ARCH_SET_FS, 0x7fd2cc787540) = 0
    Starting dash
    clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd2cc787810) = 26590
    strace: Process 26590 attached
    [pid 26589] wait4(-1,  <unfinished ...>
    [pid 26590] execve("./hw_no_shebang", ["./hw_no_shebang"], 0x557143e3c8d8 /* 25 vars */) = -1 ENOEXEC (Exec format error)
    [pid 26590] execve("/bin/sh", ["/bin/sh", "./hw_no_shebang"], 0x557143e3c8d8 /* 25 vars */) = 0
    [pid 26590] arch_prctl(ARCH_SET_FS, 0x7f3b9aa14540) = 0
    + echo Hello
    Hello
    + echo World
    World
    [pid 26590] exit_group(0)               = ?
    [pid 26590] +++ exited with 0 +++
    <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 26590
    --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26590, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
    Finished.
    exit_group(0)                           = ?
    +++ exited with 0 +++
    
    • 1

相关问题

  • 如何每 5 秒运行一次脚本?

  • 如何将必须从其自己的目录中运行的程序添加到面板或主菜单?

  • 如何编写 shell 脚本来安装应用程序列表?

  • Mac OS X Automator 的替代品?

  • 备份 bash 脚本未压缩其 tarball

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve