我在 Alpine Linux 3.20 系统上的个人 crontab 中有一个时间表,每周二至周日(即除周一外的所有日子)的 00:10 运行:
10 0 * * 2-7 "$HOME/local/sbin/backup.sh" prune-daily
这似乎也会在周一触发。为什么?
请注意,我最初的报告将症状描述为“周日不运行”。我记错了发生了什么,抱歉。在更彻底地调查症状后,我已更正了症状描述。crontab 计划是正确的,因为它从一开始就是正确的。
我在 Alpine Linux 3.20 系统上的个人 crontab 中有一个时间表,每周二至周日(即除周一外的所有日子)的 00:10 运行:
10 0 * * 2-7 "$HOME/local/sbin/backup.sh" prune-daily
这似乎也会在周一触发。为什么?
请注意,我最初的报告将症状描述为“周日不运行”。我记错了发生了什么,抱歉。在更彻底地调查症状后,我已更正了症状描述。crontab 计划是正确的,因为它从一开始就是正确的。
如果为 Vim 编辑器安装了Github Copilot 软件,它会默认启用副驾驶,这可能被视为隐私问题。
我想默认禁用副驾驶,并且仅:Copilot enable
在需要时通过编辑器手动启用它。
我怎样才能做到这一点?
我有一个 cron 任务,每 20 分钟从多个邮件服务器获取新邮件。邮件会自动分类到 下的 Maildir 邮箱中~/Mail
。
如果在过去 20 分钟内有新消息到达任何本地邮箱,我希望在 shell 中收到通知。
我正在使用zsh
shell。
我正在 KVM (QEMU) 中设置 Linux 系统,以测试在位于一组非常慢的磁盘 (RAID1 LV) 上的逻辑卷前面的快速磁盘上添加写回 LVM 缓存的效果。这是以实际物理配置为模型的,我不想触碰它,直到我知道添加缓存后它可能如何处理。
问题是,在 KVM 中,所有磁盘都以相同的速度运行,因此缓存很少被使用,而且我没有看到任何性能优势。理想情况下,我希望 RAID1 镜像能够应对 I/O,这样我就可以观察到缓存卷在写入过程中填满并逐渐写回镜像集。
有没有办法人为地限制 KVM/QEMU 中的磁盘速度?
我目前使用 Debian 12 作为此实验的主机,KVM 机器运行 Alpine Linux(也使用 Debian 12 进行测试)。KVM 设置包括一个主 qcow2 映像(快速磁盘)和附加 qcow2 映像(慢速 RAID 镜像)。
在 Mutt 中,当阅读 文件夹=account1/Unsorted
或=account1/Important
任何其他子文件夹中的消息时=account1/
,我希望默认保存文件夹(按s消息索引时建议的文件夹)为=account1/INBOX
。
同样,对于 的子文件夹=account2/
,我希望默认保存文件夹是=account2/INBOX
等。
我该如何配置 Mutt 来做到这一点?
save-hook
如果它有一种与文件夹名称匹配的方法(我不认为它有),它似乎会很有用。folder-hook
会很有用,但是没有可以用钩子设置的保存文件夹设置(有record
,但那是用于传出消息的)。在与本地 maildir 收件箱同步并使用+offlineimap
执行垃圾邮件过滤和排序后,我使用 标记邮件存储中的邮件。fdm
bogofilter
notmuch
直到最近,我还使用以下 shell 代码根据某些条件来标记和重新标记消息:
notmuch new
tr -s '\t' ' ' <<'END_BATCH' | notmuch tag --batch
-inbox +sent -- folder:/Sent/
-inbox +archive -- folder:/Archive/
-inbox +junk -- folder:/Junk/
+unsorted -- folder:/INBOX.Unsorted/
-unsorted -- not folder:/INBOX.Unsorted/
-unread -- tag:archive
+unread -- tag:unsorted
END_BATCH
这将从、或文件夹inbox
中的任何邮件中删除标签,同时使用这三个文件夹的适当标签重新标记邮件。然后,它根据消息是否位于文件夹(我放置无法分类的消息的位置)中来标记或取消标记消息。最后,我确保已归档的消息不会被标记为 ,并且未排序的消息会被标记为。Sent
Archive
Junk
INBOX.Unsorted
bogofilter
unread
unread
这很有效。
由于我通过五个不同的帐户接收邮件,因此我还想根据文件夹名称向邮件添加诸如 等标签account-somename
:account-othername
notmuch new
tr -s '\t' ' ' <<'END_BATCH' | notmuch tag --batch
-inbox +sent -- folder:/Sent/
-inbox +archive -- folder:/Archive/
-inbox +junk -- folder:/Junk/
+unsorted -- folder:/INBOX.Unsorted/
-unsorted -- not folder:/INBOX.Unsorted/
-unread -- tag:archive
+unread -- tag:unsorted
+account-acc1 -- folder:/acc1/
+account-acc2 -- folder:/acc2/
+account-acc3 -- folder:/acc3/
+account-acc4 -- folder:/acc4/
+account-acc5 -- folder:/acc5/
END_BATCH
标记似乎按预期执行,但副作用是新邮件被标记为旧邮件(从 maildir 的new
目录移动到该cur
目录)。这反过来意味着mutt
不会检测收件箱中的新消息(除非我maildir_check_cur
在mutt
配置中进行设置,我认为这不是一个很好的解决方案)。
我不知道为什么或者我能做些什么来阻止这种情况发生。
我的notmuch
配置:
[database]
path=/home/myself/Mail/inboxes
[user]
name=myname
[email protected]
[email protected]
[new]
tags=inbox;unread
[search]
[maildir]
syncronize_flags=true
[index]
header.List=List-Id
让我们假设我有两个非常复杂的jq
表达式,但它们的不同之处仅在于一个返回另一个的补码,即它们之间的唯一区别是一个做select(expression)
而另一个做select(expression|not)
。
简化示例:
$ jq -n '$ARGS.positional[] | select( . > 2 )' --jsonargs 1 2 3 4 5
3
4
5
$ jq -n '$ARGS.positional[] | select( . > 2 | not )' --jsonargs 1 2 3 4 5
1
2
与其jq
在我的代码中重复这两个不同的表达式(实际上,每个表达式只有几行),不如将一个值传递到单个表达式中以在两种行为之间切换会很整洁。
我怎样才能做到这一点?
实际jq
代码(根据消息负载中编码的文件路径过滤 RabbitMQ 消息):
map(
# Add an array of pathnames that would match this message. This
# includes the pathnames of each parent directory, leading up to
# and including the pathname of the file itself.
.tmp_paths = [
# The full pathname is part of a base64-encodod JSON blob.
foreach (
.payload |
@base64d |
fromjson.filepath |
split("/")[]
) as $elem (
null;
. += $elem + "/";
.
)
] |
# The last element is the full file path and should not have a
# trailing slash.
.tmp_paths[-1] |= rtrimstr("/")
) |
[
# Match the pathnames given as positional command line arguments
# against the computed pathnames in the "tmp_paths" array in
# each message. Extract the messages with a match.
JOIN(
INDEX($ARGS.positional[]; .);
.[];
.tmp_paths[];
if (.[1:] | any) then
.[0]
else
empty
end
)
] |
# Deduplicate the extracted messages on the full pathname of the file.
# Then remove the "tmp_paths" array from each message and base64 encode
# them.
unique_by(.tmp_paths[-1])[] |
del(.tmp_paths) |
@base64
我假设我需要if
以某种方式修改该语句以使其提取或丢弃其文件路径与作为位置参数给出的路径名匹配的消息。
在我的 FreeBSD 13.2 系统上,该zless
实用程序无法查看使用gzip
或压缩的文本文件compress
,警告它们可能是二进制文件,然后如果我说我想查看内容则显示垃圾。奇怪的是,使用zmore
orgunzip -c
似乎有效。
$ zless znapzend.log.1.gz
"znapzend.log.1.gz" may be a binary file. See it anyway?
(肯定的回答将二进制数据发送到终端。)
$ zless --version
less 608 (POSIX regular expressions)
Copyright (C) 1984-2022 Mark Nudelman
less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Home page: https://greenwoodsoftware.com/less
$ zmore --version
less 608 (POSIX regular expressions)
Copyright (C) 1984-2022 Mark Nudelman
less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Home page: https://greenwoodsoftware.com/less
这是什么原因?
在awk
中,和函数的第一个参数、sub()
函数gsub()
的第二个参数match()
和可选的第三个参数split()
是一个扩展的正则表达式。
这样的参数可以是任意表达式,其计算结果为被解释为正则表达式的字符串,也可以是正则表达式常量。
在中,为一些正则表达式(文法中的“token” )awk
写了一个正则表达式常量。/RE/
RE
ERE
awk
问题:假设它RE
保持不变(一些非变量正则表达式),在调用using/RE/
和 using "RE"
(语法中的“STRING
标记” )之间是否存在任何实际差异,例如?或者:是否有任何已知的实现在对上述函数的调用中这两种表示正则表达式的方式之间有所不同?awk
sub()
awk
问的原因是我记得必须修改一些awk
代码,这些代码试图在对or"RE"
的调用中用作正则表达式,因为无论出于何种原因,手头的实现都做了错误的事情,除非我用 调用函数。sub()
gsub()
awk
/RE/
不幸的是,这是一段时间以前(2 年多)所以我不记得细节,我什至不确定我当时使用的是什么 Unix(可能是 OpenBSD),但从那以后我一直想问这个问题。
在无头 Ubuntu 22.04 机器上,我想在 VirtualBox 中开始无头安装 NetBSD 9.2。
我有一个准备好的虚拟机,附有一组空白磁盘映像,以及附在 CDROM 驱动器上的可引导 NetBSD 安装 CD。
我的想法是通过串行端口执行安装,使用minicom
,但我无法让安装切换到使用串行控制台。
我正在启动机器
VBoxManage startvm netbsd --type=headless
然后我尝试让它将控制台切换到串行端口:
VBoxManage controlvm netbsd keyboardputfile boot.conf
...boot.conf
包含一行文字的文件在哪里consdev com0
,这是您在 NetBSD 引导提示符上键入以切换到串行控制台的内容。
我知道 NetBSD 的串行控制台设置为使用 9600 8N1,这是我minicom
配置使用的,并且我在虚拟机上设置了串行端口,如下所示:
UART 1: I/O base: 0x03f8, IRQ: 4, attached to pipe (server) '/tmp/netbsd.pipe', 16550A
我开始minicom
使用
minicom -D 'unix#/tmp/netbsd.pipe'
我以相同的方式在另一台虚拟机上成功使用串行控制台,并且minicom
在 NetBSD 机器启动后,我可以看到从“离线”切换到“在线”的状态,但minicom
.
谁能看到问题是什么以及我将如何解决它?我知道替代方法是 PXE 引导机器,但我希望能够避免这样做(因为我目前没有网络引导其他任何东西)。
我需要在一个相当大的目录层次结构中搜索名称与特定文件名通配模式匹配的常规文件。层次结构是如此之大(非常深并且有一些巨大的目录),以至于采取幼稚的方法需要很长时间:
find /top/dir -type f -name 'pattern'
pattern
(像 . 的一些模式在哪里*proj*.tgz
。)
由于目录结构的性质,我知道如果find
在目录中找到文件,我可以引入优化来修剪搜索树。例如,在特定目录中找到一个或多个文件意味着我不需要检查该特定目录的任何子目录以查找其他匹配项。
由于应用-prune
到常规文件没有做正确的事情,我不能只是做
find /top/dir -type f -name 'pattern' -prune
问题:如何避免搜索包含与模式匹配的文件的目录的子目录?
在尝试模仿我的 OpenBSD 当前系统上的示例时,我正在关注为 RHEL 6 编写的SSH 证书和(这使得它大约有 10 年的历史)的相当好的文本。openssh-5.3p1-94.el6
其中一个示例显示创建主机 CA 密钥,然后签署主机的 RSA 密钥:
ssh-keygen -s ~/.ssh/ca_host_key -I host_name -h -Z host_name.example.com -V -1w:+54w5d /etc/ssh/ssh_host_rsa.pub
Enter passphrase:
Signed host key /root/.ssh/ssh_host_rsa-cert.pub: id "host_name" serial 0 for host_name.example.com valid from 2015-05-15T13:52:29 to 2016-06-08T13:52:29
当我在 OpenBSD 上尝试这个时,我没有得到for host_name.example.com
输出。文中说
该
-Z
选项将此证书限制为域中的特定主机。
...而且我对此感到有些困惑,因为OpenBSD 手册ssh-keygen(1)
根本没有提到任何-Z
选项。我也对ssh-keygen
接受这个无证选项而不抱怨感到困惑。
查看的源代码ssh-keygen
,该-Z
选项被接受,但似乎与“格式密码”(或可能是“密码格式”)有关,而不是与主机名有关(前提是我正在查看正确的代码):
case 'Z':
openssh_format_cipher = optarg;
break;
查看旧版本的代码,它总是与“格式密码”有关。
OpenSSH 的发行说明没有提及-Z
.
问题:是否ssh-keygen
在 RHEL 6 上(我不确定该版本是否相关,但关于 RHEL 7 或 RHEL 8 的 SSH 证书的等效文档似乎不可用)使用 RedHat-only 补丁进行修补,使-Z
行为有所不同?
我之前已经注意到了这一点,但是当我回答“如何将目录移动到同名的目录中? ”时,它又被提出来了:
就环境变量而言,macOS 上的mktemp
实用程序与 Linux 或 BSD(或至少 OpenBSD)上的同名实用程序的行为不同。TMPDIR
要在当前目录中创建一个临时文件,我通常可以说
tmdfile=$(TMPDIR=. mktemp)
或者
tmpfile=$(TMPDIR=$PWD mktemp)
(对于带有 的临时目录也是如此mktemp -d
)。
在 macOS 上,我将不得不通过给它一个实际的模板来强制实用程序使用当前目录,如
tmpfile=(mktemp ./tmp.XXXXXXXX)
因为使用更方便tmpfile=$(TMPDIR=. mktemp)
会忽略TMPDIR
变量并/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T
在类似命名的目录下或中创建文件。
macOS 上的手册mktemp
提到
如果
-t prefix
给出选项,mktemp
将根据前缀和_CS_DARWIN_USER_TEMP_DIR
配置变量(如果可用)生成模板字符串。后备位置(如果_CS_DARWIN_USER_TEMP_DIR
不可用)是TMPDIR
和/tmp
。
在我的系统上,_CS_DARWIN_USER_TEMP_DIR
似乎未设置:
$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'
但是例如
tmpfile=$(TMPDIR=. mktemp -t hello)
仍然在下创建一个文件/var/folders/.../
(也$PWD
用于代替.
)。
我注意到
$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/
但这对我没有多大帮助,因为我不知道如何更改此值。
据说macOSmktemp
实用程序来自 FreeBSD,而后者又从 OpenBSD 获得它(这肯定是很久以前的事了)。
问题:
这是 macOS 实现中的错误(或遗漏)mktemp
吗?如何从脚本中更改DARWIN_USER_TEMP_DIR
值(或_CS_DARWIN_USER_TEMP_DIR
手册中提到的)(理想情况下,我希望取消设置它以便$TMPDIR
优先)?
我想使用通用ntpd
守护程序来测试虚拟机是否保持时间,而不让它实际调整时钟。
我在 macOS 系统上的 VirtualBox 中运行 Solaris 11.4(Oracle 的英特尔标准映像),但我无法获得正确同步的时间。令我震惊的是,VM 很可能已经在使用 VirtualBox Guest Additions 来执行此操作(我不知道这是如何工作的),并且我可能会通过ntpd
在来宾中运行来打乱时间保持。
为了测试这一点,我想我ntpd
应该在 Solaris VM 中设置来监控一些公共时间服务器,但不知何故阻止它修改本地时钟。这样我就可以查看loopstats
和peerstats
日志如何随着时间的推移而查看本地时钟是否真的保持良好的时间。
问题是我找不到任何关于如何停止ntpd
调整本地时钟的提示。
我过去也想在我使用openntpd
(来自 OpenBSD)进行实际计时的系统上执行此操作。然后,ntpd
守护进程可以坐在后台进行监控,而不会干扰。但是我当时也找不到任何方法来实现这一点。
我几乎可以肯定这不是zsh
shell 提供的一种方式,但我想我还是会问一下,以确保我没有遗漏手册中的任何内容。
使用zsh
shell,我可以从具有模式的目录中挑选出两个最大的可见文件
*(.OL[1,2])
如果我有一组目录,并且我希望每个目录都有两个最大的文件,我相信我必须遍历各个目录然后使用
$dirpath/*(.OL[1,2])
(其中$dirpath
是当前循环迭代中的目录路径)。
很高兴能够说
*/*(.OL[1,2])
但是那个 glob 限定符将作为一个整体应用于匹配名称的列表,我会得到两个匹配项,而不是每个目录中的两个匹配项。
问题:是否可以将限定符的“范围”限制为仅以某种方式影响最近的路径组件?
使用glob 限定符可以以zsh
各种方式对文件名通配模式匹配的结果进行排序。例如,该模式*(om)
将匹配当前目录中的所有非隐藏名称,按修改时间戳排序。
但是,我有时想要一种随机排序的方法(例如,获取文件的随机抽样)。据我所见,没有直接执行此操作的限定符。
问题:如何从zsh
文件名通配模式中获取路径名的随机列表?
考虑命令
eval false || echo ok
echo also ok
通常,我们希望它执行false
实用程序,并且由于退出状态非零,然后执行echo ok
and echo also ok
。
在我使用的所有类似 POSIX 的 shell(、、、、、OpenBSD和)ksh93
中zsh
,都会发生这种情况bash
,但如果我们启用.dash
ksh
yash
set -e
如果set -e
生效,OpenBSDsh
和ksh
shell(均源自pdksh
)将在执行eval
. 没有其他外壳可以做到这一点。
POSIX 表示特殊内置实用程序(例如eval
)中的错误应该导致非交互式 shell 终止。我不完全确定执行是否false
构成“错误”(如果是,它将与set -e
活动无关)。
解决此问题的方法似乎是将其放入eval
子外壳中,
( eval false ) || echo ok
echo also ok
问题是我是否应该在一个 POSIX-ly 正确的 shell 脚本中这样做,或者这是否是 OpenBSD 的 shell 中的一个错误?另外,上面链接的 POSIX 文本中的“错误”是什么意思?
额外信息:OpenBSD shell 将 在命令中执行echo ok
有和无set -e
eval ! true || echo ok
我的原始代码看起来像
set -e
if eval "$string"; then
echo ok
else
echo not ok
fi
使用OpenBSD 外壳不会输出(它会终止),我不确定这是设计使然,错误或误解,还是其他原因。not ok
string=false
假设我有一个关联数组bash
,
declare -A hash
hash=(
["foo"]=aa
["bar"]=bb
["baz"]=aa
["quux"]=bb
["wibble"]=cc
["wobble"]=aa
)
我不知道键和值(实际数据是从外部源读取的)。
如何创建对应于相同值的键数组,以便我可以在所有唯一值的循环中执行
printf 'Value "%s" is present with the following keys: %s\n' "$value" "${keys[*]}"
并获取输出(不一定按此顺序)
Value "aa" is present with the following keys: foo baz wobble
Value "bb" is present with the following keys: bar quux
Value "cc" is present with the following keys: wibble
重要的是,键作为单独的元素存储在keys
数组中,因此不需要从文本字符串中解析出来。
我可以做类似的事情
declare -A seen
seen=()
for value in "${hash[@]}"; do
if [ -n "${seen[$value]}" ]; then
continue
fi
keys=()
for key in "${!hash[@]}"; do
if [ "${hash[$key]}" = "$value" ]; then
keys+=( "$key" )
fi
done
printf 'Value "%s" is present with the following keys: %s\n' \
"$value" "${keys[*]}"
seen[$value]=1
done
但是双循环似乎有点低效。
有没有我错过的数组语法bash
?
例如,这样做zsh
会让我访问更强大的数组操作工具吗?
在 Perl 中,我会做
my %hash = (
'foo' => 'aa',
'bar' => 'bb',
'baz' => 'aa',
'quux' => 'bb',
'wibble' => 'cc',
'wobble' => 'aa'
);
my %keys;
while ( my ( $key, $value ) = each(%hash) ) {
push( @{ $keys{$value} }, $key );
}
foreach my $value ( keys(%keys) ) {
printf( "Value \"%s\" is present with the following keys: %s\n",
$value, join( " ", @{ $keys{$value} } ) );
}
但是bash
关联数组不能保存数组...
我也对任何可能使用某种形式的间接索引的老派解决方案感兴趣(在读取我在hash
上面所说的值时构建一组索引数组?)。感觉应该有一种方法可以在线性时间内做到这一点。
我计划通过安装最新的 OpenBSD 快照来设置一个新的个人 OpenBSD-current 系统,并且我希望它在对文件进行的本地更改方面看起来或多或少类似于我现有的 OpenBSD-current 系统在/etc
没有实际将目录复制/etc
到新系统的情况下(它还包含新系统不应该使用的配置,以及其他应该不同的东西)。
将我的旧设置与原始系统的设置进行比较的最简单方法是什么,以便我可以手动完成并设置新机器?我想在安装新的 OpenBSD 系统后编译我需要配置的单个基本系统服务等的列表,作为一种不会意外遗漏的方法,例如为 root 设置邮件别名。
根据其手册yash
, shell 有一个printf
内置的。
但是,这是我在yash
默认配置的 shell 中看到的:
$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf
这个shell中是否printf
内置了一个?对于许多其他所谓的内置实用程序,这些实用程序也可作为外部命令使用,结果是相似的。
作为比较,在pdksh
(ksh
在 OpenBSD 上, whereprintf
不是内置的):
$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf
并且在bash
(哪里printf
是内置的):
$ command -v printf
printf
$ type printf
printf is a shell builtin