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
    • 最新
    • 标签
主页 / unix / 问题 / 784380
Accepted
User051209
User051209
Asked: 2024-10-02 18:23:49 +0800 CST2024-10-02 18:23:49 +0800 CST 2024-10-02 18:23:49 +0800 CST

在启动脚本的服务文件中设置StandardOutput=null是否相当于将脚本的标准输出重定向到/dev/null?

  • 772

我当前的服务和 Shell 脚本

我有一个名为的 systemd 服务文件myservice.service。该服务在启动时启动。该服务启动 shell 脚本/usr/bin/myscript.sh,如下面的部分所示[Service]:

...
[Service]
Type=forking
ExecStart=/usr/bin/myscript.sh
PIDFile=/dev/shm/myscript.pid
...

脚本内容如下:

#!/bin/sh
/usr/bin/script-python.py > /dev/null &
echo $! > /dev/shm/myscript.pid

shell 脚本myscript.sh启动 Python 脚本:script-python.py。通过重定向,> /dev/null的标准输出script-python.py被发送到/dev/null,因此丢失。

更改为使用 Service->StandardOutput=null

在StandardOutput 的 systemd 文档中我读到了以下句子:

null将标准输出连接到 /dev/null,即写入其中的所有内容都将丢失。

因此,我考虑对我的文件执行以下更改:

  1. myservice.service变为(添加StandardOutput=null):
...
[Service]
Type=forking
ExecStart=/usr/bin/myscript.sh
PIDFile=/dev/shm/myscript.pid
StandardOutput=null
...
  1. myscript.sh变为(删除>/dev/null):
#!/bin/sh
/usr/bin/script-python.py &
echo $! > /dev/shm/myscript.pid

我的问题

我的问题是:如果我进行上述修改,结果与我现在的情况完全相同:所有输出都script-python.py丢失了?没有任何区别吗?

shell-script
  • 1 1 个回答
  • 37 Views

1 个回答

  • Voted
  1. Best Answer
    Stewart
    2024-10-03T15:10:05+08:002024-10-03T15:10:05+08:00

    这两者几乎是等价的:

    [Service]
    ExecStart=/bin/sh -c '/usr/bin/script-python.py >/dev/null'
    

    和

    [Service]
    ExecStart=/bin/sh -c '/usr/bin/script-python.py'
    StandardOutput=null
    

    第一个会将脚本stdout的重定向.py到/dev/null。第二个会将stdout整个sh脚本的 重定向到/dev/null。在这种情况下,它们是等效的,但如果您的sh脚本包含其他行,它们不会被静音(只是script-python.py)。


    正如我在评论中提到的,您的脚本似乎是为较旧的 SysV init 系统编写的。它可以与systemdwith配合使用Type=forking,但它明确地执行了本systemd应自动为您完成的操作。

    如果我要将其集成到我的一台机器上,我会删除/usr/bin/myscript.sh并使用这个服务文件:

    [Service]
    ExecStart=/usr/bin/script-python.py
    StandardOutput=null
    

    您可以看到这要简单得多。

    只要script-python.py不会向 stdout 发送垃圾邮件,我可能还会删除该StandardOutput=行并让它journald处理它。我有时会看到人们使用,>/dev/null因为他们从终端手动运行脚本,并希望将该终端重新用于其他事情而不受 stdout 的干扰。当它是一项服务时,这不是一个问题。

    以下是对每一行更改的解释:

    • ExecStart=/usr/bin/script-python.py:Systemd 可以直接运行 Python 脚本。这在 SysV init 中是不可能的。这避免了不必要地调用sh。
    • 已删除 Type=forking:sh您最初拥有的脚本将 fork ( &),允许script-python.py在后台运行。这就是服务过去的工作方式。由于我们script-python.py直接运行,因此我们不需要这个。默认设置会导致 systemd直接Type=simple监视。script-python.py
    • 已删除 PIDFile=:仅与 一起使用Type=forking。它有助于systemd了解应将哪个分叉进程作为主进程进行跟踪。 systemd如果只有一个子进程,则可以很好地猜测,因此无论如何它都可能已被删除。

    其他几点说明:

    • 您的PIDFile=位于/dev/shm/。放置它的位置很奇怪,因为该设备通常由共享内存调用来管理。 /run/script-python.pid如果您决定保留它,会更合适。

    • sysV init 脚本会将 PID 保存到文件中,以便稍后检索以停止/重新启动。在systemd管理服务时,这没有必要,因为 PID 是在内部跟踪的,并且终止信号由其他选项定义。

      #!/bin/sh
      case $1 in
        start)
          /bin/foo &                # notice the fork.  foo will continue after sh finishes
          echo $! > /run/foo.pid    # Write the PID to a file for later recall
          ;;
        stop)
          pid=$(cat /run/foo.pid)   # Recall the PID
          /bin/kill $pid            # Use that PID to kill the process
          ;;
      esac
      

    然后用户可以使用以下命令启动/停止脚本

    /etc/init.d/foo.sh start
    /etc/init.d/foo.sh stop
    

    现已替换为

    systemctl start foo
    systemctl stop foo
    
    • 2

相关问题

  • 在awk中的两行之间减去相同的列

  • 打印文件行及其长度的脚本[关闭]

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 按分隔符拆分并连接字符串问题

  • MySQL Select with function IN () with bash array

Sidebar

Stats

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

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve