我有一个程序可以生成有用的信息,stdout
但也可以从stdin
. 我想将其标准输出重定向到一个文件,而不在标准输入上提供任何内容。到目前为止,很好:我可以做到:
program > output
Run Code Online (Sandbox Code Playgroud)
并且不要在 tty 中做任何事情。
但是,问题是我想在后台执行此操作。如果我做:
program > output &
Run Code Online (Sandbox Code Playgroud)
程序将被挂起(“挂起(tty 输入)”)。
如果我做:
program < /dev/null > output &
Run Code Online (Sandbox Code Playgroud)
程序立即终止,因为它到达 EOF。
似乎我需要的是将program
某些内容导入到无限期不执行任何操作且不读取的内容中stdin
。以下方法有效:
while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &
Run Code Online (Sandbox Code Playgroud)
然而,这一切都非常难看。有有是一种优雅的方式,使用标准的Unix工具,以“什么都不做,无限期”(意译man true
)。我怎么能做到这一点?(我这里优雅的主要标准:没有临时文件;没有忙碌等待或定期唤醒;没有异国情调的实用程序;尽可能短。)
经典情况:我跑得不好rm
,之后立即意识到我删除了错误的文件。(没什么重要的,我最近的备份还算可以,但还是很烦人。)
知道如果我想使用extundelete
或此类工具恢复文件,进一步的磁盘活动是我的敌人,我立即关闭了机器的物理电源(即,使用电源按钮,而不是使用halt
或任何此类命令)。这是一台没有运行重要任务或任何打开的笔记本电脑,所以这是一个可以接受的操作。(顺便说一下,从那时起我了解到在这种情况下要做的第一件事是首先估计丢失的文件是否仍然可以被进程打开https://unix.stackexchange.com/a/101247 --如果是,您应该通过这种方式恢复它们,而不是关闭机器。)
尽管如此,一旦机器断电,我想了一会儿,并认为这些文件不值得花时间启动实时系统进行适当的取证。所以我重新启动了机器。然后我发现我的文件仍然位于磁盘上:rm
在我关闭电源之前还没有传播到磁盘。我跳了一小段舞,感谢系统管理员之神出人意料的宽恕。
我现在的问题是要了解这是如何可能的,以及rm
实际传播到磁盘之前的典型延迟是多少。我知道磁盘 IO 不会立即刷新,而是在内存中停留了一段时间,但我认为磁盘日志会很快确保挂起的操作不会完全丢失。https://unix.stackexchange.com/a/78766似乎暗示了一种单独的机制来刷新脏页和刷新日志操作,但没有提供足够的细节来说明日志将如何参与 arm
以及之前的预期延迟操作被刷新。
更多细节:数据位于 LUKS 卷内的 ext4 分区中,在启动机器备份时,我看到以下内容syslog
:
Sep 24 10:24:58 gamma kernel: [ 11.457007] EXT4-fs (dm-0): 1 orphan inode deleted
Sep 24 10:24:58 gamma kernel: [ 11.458393] EXT4-fs (dm-0): recovery complete
Sep 24 10:24:58 gamma kernel: [ 11.482475] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null)
Run Code Online (Sandbox Code Playgroud)
但我不相信它与rm
.
另一个问题是是否有办法告诉内核不要执行任何挂起的磁盘操作(而是将它们转储到某处),而不是关闭机器电源。(当然,不执行挂起的操作听起来很危险,但这就是在关闭机器电源时会发生的情况,并且在某些情况下它可以拯救您。)当然,这将是“更干净”,也很有趣例如,对于物理断电不是一个简单选择的远程服务器。
在尝试调试我的 mutt 配置时,我需要查看正在运行的mutt
进程中某些配置设置的值是什么。我如何确定变量的当前值是mutt
多少?
我使用 gpg-agent 有时没有 X 显示或通过 ssh,所以我的配置文件包含:
pinentry-program /usr/bin/pinentry-curses
Run Code Online (Sandbox Code Playgroud)
这样,在curses 中请求gpg 密码。
也就是说,在一些图形脚本中,我希望改用 GTK pinentry。如何调用 gpg 并临时使用不同的 pinentry?
我rsync
用来备份远程机器上的大硬盘。默认情况下,rsync
当远程机器上的文件不再存在于本地机器上时,不会删除它们。这很有用,因为它可以恢复,例如,如果我想恢复一个被错误删除的文件,这也意味着我不需要担心 rsync'ing 一个空目录(如果硬驱动器死亡或未安装)。问题是它在远程主机上占用了大量磁盘空间,而且如果我需要恢复备份,它将被这些已删除的文件污染。
替代方法是rsync --delete
,但这意味着已删除的文件也将在我第一次运行备份时被删除,如果挂载点变为空,那么我也有删除备份的风险。
理想情况下,我希望有一种方法可以告诉rsync
执行 like --delete
,但不是删除文件,而是可以将它们移动到不同的备份层次结构。这样,如果我愿意,我仍然可以恢复这些文件,我可以清理第二个层次结构中的较大文件以节省空间,而主备份层次结构将是我驱动器的干净备份。
有没有办法模仿这种行为?(或一些类似的行为)
(我没有足够的磁盘空间来维护远程主机上的两个完整备份。另外,我知道增量备份工具的存在,例如Borg Backup,但我想要一个不依赖重型工具的解决方案自定义存储格式。我也有点担心使用硬链接的解决方案,但如果它是最好的选择,我可以接受。)
我正在使用 mutt 别名来缩写收件人姓名(例如,jdoe
被定义为 的别名john.doe@example.com
)。但是,如果我输入错误的别名(例如,jdeo
),mutt 不会警告我别名不存在的事实。相反,它使用$hostname
变量自动完成此操作,例如,如果我的机器具有主机名,foo.mydomain.net
则假别名将被替换为jdeo@foo.mydomain.net
. 这绝不是我打算做的。
因此,如果我输入错误的别名,我不会收到任何警告,我必须希望,在发送邮件时,远程 SMTP 会拒绝它(“本地收件人表中的用户未知”)或向我发送邮件状态通知......这并不理想,我已经搞砸了几次。
相反,我希望 mutt 警告我不存在的别名,即,如果我键入的收件人不包含“@”并且不是已知别名,则 mutt 应该抱怨并拒绝发送邮件。
是否可以配置 mutt 来警告不存在的别名?我找不到相关的配置选项。我也尝试设置$hostname
为空字符串,但随后 mutt 愉快地联系了远程 SMTP 并尝试将邮件发送到“jdeo”。
我正在尝试配置mutt
绑定以将电子邮件通过管道传输到ssh
调用中,以使用脚本在远程计算机上处理邮件,该脚本使用less
. 但是,这不起作用,因为less
只是给了我没有分页的整个输出。
试图缩小范围,我基本上试图模仿的是:
seq 1 100 | less
Run Code Online (Sandbox Code Playgroud)
但是less
在远程机器上运行。(因为我的用例是在 mutt 中调用脚本,seq 1 100
部分(代表电子邮件)不能在远程机器上运行,也不能less
在本地机器上运行(代表较少的脚本)部分。)
如果我做:
seq 1 100 | ssh -t REMOTE_MACHINE less
Run Code Online (Sandbox Code Playgroud)
我收到警告“将不会分配伪终端,因为标准输入不是终端。” 并less
直接显示输出而不做任何分页。
如果我做:
seq 1 100 | ssh -t -t REMOTE_MACHINE less
Run Code Online (Sandbox Code Playgroud)
less
因“缺少文件名(“less --help”寻求帮助)”而失败,所以我猜它的输入丢失了。
我也尝试添加zsh -ic
,但没有效果。什么是正确的ssh
调用,以便less
在远程主机上可以读取其标准输入并照常进行分页?
编辑以尝试回答下面 Gilles 的评论:如果less
上面示例中的调用被实际脚本替换,也会出现问题。如果我创建一个script.sh
包含以下内容的可执行文件:
#!/bin/bash
exec less
Run Code Online (Sandbox Code Playgroud)
我把它放在我家里的本地和远程机器上,然后以下工作:
seq 1 100 | ~/script.sh
Run Code Online (Sandbox Code Playgroud)
但下列情况不(带 …
假设我有一台 Debian 机器,我想通过删除无用的包来释放 '/' 上的空间。为了找到要审查的优秀候选包,我想首先将注意力集中在最大的包上。
似乎这样做的标准解决方案是按安装大小列出所有已安装的软件包。然而,这个解决方案有很多缺点,因为它忽略了依赖关系,忽略了一个包是自动安装还是手动安装:
似乎这项工作的正确工具应该只建议手动安装的软件包进行删除,并且应该通过删除它们然后运行 autoremove(删除不再需要的自动安装的软件包)将回收的空间对它们进行排序。
当然,您可以通过此解决方案的变体来模拟这一点,但它既缓慢又丑陋。因此我的问题是:是否有一个标准工具可以查看包的依赖关系图并计算这些信息?(我正在考虑为此编写一个脚本,但我想确保它还不存在。)
我非常喜欢使用ncdu实用程序来了解目录中的空间使用情况。
但是,我有一个用例,我尝试选择要备份的文件夹和不备份的文件夹,并且备份将被压缩(作为 .tar.xz 存档,但我认为 .tar.gz 会产生相同的结果)结果符合我的想法)。因此,直观上,我不太关心大但压缩效果好的文件(例如,电子邮件存档),而我更关心相对较小但根本无法压缩的文件(例如,JPG 图片)。我想查看按压缩大小排序的文件和文件夹,而不是按实际未压缩大小排序。
一个自然的解决方案是压缩所有文件,然后使用类似的工具对存档ncdu
进行操作,告诉我文件夹如何占用存档中的空间。
有这样的实用工具吗?
我对 GUI 程序很满意(尽管我更喜欢基于文本的程序),并且我对仅适用于不同压缩算法的方法也很满意,因为我认为它们仍然会产生有用的结果(例如,复制文件系统中的层次结构)具有内置压缩/重复数据删除功能)。
I was playing around with date
to try to convert expressions such as "2 hours" to a number of seconds like 7200. I thought I could perform this with invocations such as:
date -d "1970-01-01 00:00:00 + 2 hours" +"%s"
Run Code Online (Sandbox Code Playgroud)
Yet, I noticed extremely strange results while so doing. (My /etc/timezone
contains "Europe/Paris", hence the use of TZ
to force UTC times.)
omega:~$ TZ=utc date -d "1970-01-01 00:00:00" +"%s"
0
omega:~$ TZ=utc date -d "1970-01-01 00:00:00 + 0 minutes" +"%s" …
Run Code Online (Sandbox Code Playgroud) disk-usage ×2
mutt ×2
apt ×1
backup ×1
bash ×1
compression ×1
coreutils ×1
date ×1
debian ×1
gpg ×1
gpg-agent ×1
journaling ×1
less ×1
linux-kernel ×1
ncurses ×1
rm ×1
rsync ×1
shell ×1
shell-script ×1
software-rec ×1
ssh ×1
stdin ×1
stdout ×1
terminal ×1