Bash 脚本没有被记录

Bash 脚本没有被记录

因此,我在这里玩一些 bash 脚本,但有些东西不起作用:

#!/bin/bash

script -c \
sudo apt-get update &&
sudo apt-get upgrade &&

exit

echo "(Not important for the question)"

我想运行通常的更新和升级内容,并记录输出,但是当我运行脚本时,它只说脚本开始在 apt-get 中记录,显示 sudo 的用法(usage: sudo -h是第一行),并说脚本已完成。之后它启动 sudo 内容。

我需要做什么才能记录更新和升级任务的输出?一般来说,我怎样才能记录整个 shell 脚本的输出?

答案1

如果我正确理解了您的问题,您可以使用以下内容:

#!/bin/bash

apt-get update &> update.log
apt-get -y upgrade &> upgrade.log

echo "all done"

将此脚本另存为run_updates.sh,使用 使其可执行chmod 755 run_updates.sh,然后使用 运行它sudo ./run_updates.sh
如果要将所有输出保存在一个文件中,请从脚本中删除&> updates.log和,然后以以下方式运行脚本&> upgrades.logsudo./run_updates.sh &> run_updates.log


脚本说明:

  • apt-get update &> update.log运行apt-get update并将输出保存在update.log
  • apt-get -y upgrade &> upgrade.log运行apt-get upgrade并将输出保存在 中upgrade.log。这-y将阻止 apt 询问是否继续(它假定“是”)

关于重定向的说明:
您可以使用下面的重定向将命令或脚本的输出“发送”到文件。

  • &>重定向 STDOUT 和 STDERR
  • >1>重定向 STDOUT
  • 2>重定向 STDERR

关于 sudo 的说明:
这可能是您收到错误的原因。在运行sudo脚本中需要的命令时,最好将命令放在sudo脚本中,然后使用 运行脚本sudo。否则,您将不得不以某种方式向脚本提供 sudo 密码,这很糟糕。


编辑:
在下面的代码中,两个 apt 命令的输出都重定向到update.log。双>( >>) 用于将数据附加到文件(而不是替换它)

#!/bin/bash

apt-get update &> update.log
apt-get -y upgrade &>> update.log

echo "all done"

答案2

一般来说,要记录整个脚本的输出,请重定向整个脚本的输出:

exec &> some.log
# Or, when using `/bin/sh`:
# exec >some.log 2>&1

内置exec通常用于改变 shell 已经打开的文件描述符或者添加新的文件描述符(输入和输出的源和目标)。

例如,给定example.sh

#! /bin/bash
exec &> some.log
ls foo
echo foo

跑步时:

$ ./example.sh
$ cat some.log
ls: foo: No such file or directory
foo

如果您希望同时输出到屏幕和文件,请使用tee进程替换:

exec &> >(tee some.log)

答案3

不需要脚本,只需使用 Bash 重定向在一行中完成即可tee

{ sudo apt-get update && sudo apt-get upgrade ; } |& tee output.txt

如果您想将输出附加到现有的日志文件,请-a在后面添加选项tee


解释一下它的作用:

  • { ... ; }将命令分组到里面,这样我们将执行的输出重定向将应用于所有命令,而不仅仅是最后一个命令。请注意所有命令前后...的空格以及分号!{};(感谢@kos 告诉我避免生成子 shell)
  • sudo apt-get update && sudo apt-get upgrade是我们要在此处运行和记录的示例命令。您可以将整个部分替换为任何您喜欢的内容。
  • |&(“管道”)将其左侧命令的两个输出流(STDERR/标准错误和STDOUT/标准输出)重定向到右侧命令的STDIN(标准输入)。(感谢@muru 教我如何&重定向 STDOUT 和 STDERR)
  • tee output.txt将其读取的所有内容从 STDIN 复制到 STDOUT,并将其保存到output.txt。 如果目标文件已存在,它将被静默覆盖。 如果您使用 ,则可以将其附加到文件tee -a output.txt

相关内容