Debian 11 附带了 gnome-tweaks 3.34,它有一个“顶部栏”菜单栏。我特别依赖“秒”选项。定期刷新屏幕有助于让我确信 VNC 连接尚未断开。
我将 Fleet 升级到 Debian 13,其中包含 gnome-tweaks 46.1。我注意到没有“顶部栏”菜单。
它已经移动到别处了吗?我试图在上游发行说明中查找一些内容,但 gitlab 上唯一的发行版已有 7 年历史。
Debian 11 附带了 gnome-tweaks 3.34,它有一个“顶部栏”菜单栏。我特别依赖“秒”选项。定期刷新屏幕有助于让我确信 VNC 连接尚未断开。
我将 Fleet 升级到 Debian 13,其中包含 gnome-tweaks 46.1。我注意到没有“顶部栏”菜单。
它已经移动到别处了吗?我试图在上游发行说明中查找一些内容,但 gitlab 上唯一的发行版已有 7 年历史。
有时如果我git checkout
,甚至make
,我最终会得到一些意想不到的输出,这让我问:
等一下,什么?我们再看看。
我的选择通常是:
dpkg-buildpackage
对于由于配置错误而失败的命令cmake
,它们会在错误发生后打印大量的调试数据,因此您真的必须回滚很长很长的距离。| more
。
git checkout
。是否有一个终端可以轻松浏览以前命令的输出?
complete
当选项中${COMPREPLY[@]}
包含字符时,我无法提供完整的建议:
。相反,它只提供所有建议共有的前缀。
这是一个运行良好的例子:
_foo()
{
local cur=${COMP_WORDS[$COMP_CWORD]}
COMPREPLY=( $(compgen -W "bart baze" -- "$cur" ) )
}
complete -F _foo foo
以下是它的使用方法(我从不按Enter,只TAB在指示的地方按)
$ foo <tab>
$ foo ba <-- Autocompletes common prefix, good
$ foo ba<tab>
bart baze <-- Suggests options, good
$ foo bar<tab>
$ foo bart <-- Autocompletes the only option, good
但是,如果我在前面添加一些内容:
,例如http://
,它就无法提供完整的建议(仅提供所有选项共有的前缀):
$ _foo()
{
local cur=${COMP_WORDS[$COMP_CWORD]}
COMPREPLY=( $(compgen -W "h:bart h:baze" -- "$cur" ) )
}
$ complete -F _foo foo
$ foo <tab>
$ foo h:ba <-- Autocompletes common prefix, good
$ foo h:ba<tab>
$ foo h:ba <-- No effect
该手册对-I
使用分隔符提出了一些建议,但complete -I -F _foo foo
并没有改变任何内容。
如果我深入检查,它似乎与如何complete -F
解释有关${COMPREPLY[@]}
。 compgen
似乎设置得COMPREPLY
很好。
$ COMPREPLY=( $(compgen -W "h:bart h:baze" -- h) )
$ for i in "${COMPREPLY[@]}"; do echo "$i"; done
h:bart
h:baze
我有一个具有这种用法的脚本:
myscript [options] positional-args... -- [fwd-params]
因为[options]
可以有长或短的变体,我喜欢使用getopt
.但我有麻烦了。
我getopt
这样使用:
args=$(getopt -o a:,b --long alpha:,gamma -- "$@")
eval set -- "$args"
while : ; do
case "$1" in
-a | --alpha) a="$2" ; shift 2 ;;
-b ) b=true ; shift ;;
--gamma ) g=true ; shift ;;
-- ) shift ; break ;;
esac
done
positionals=()
while [ $# -gt 0 ] ; do
case "$1" in
* ) positionals+=("$1"); shift ;;
-- ) shift ; break ;;
esac
done
# What-ever is left in "$@" needs to be forwarded to another program
backend "$@"
如果我没有的话,这非常有用[fwd-params]
:
$ getopt -o a:,b -- -a 1 -b pos1 pos2
-a '1' -b -- 'pos1' 'pos2'
^-- getopt adds this to help me find
the end-of-options/start-of-positionals
但如果用户定义了任何[fwd-params]
.这是我想要的输出:
$ getopt -o a:,b -- -a 1 -b pos1 pos2 -- fwd1
-a '1' -b -- 'pos1' 'pos2' '--' 'fwd1'
^
\- I'll use this to delimit
the positional arguments
from the forwarding ones.
这就是我实际得到的。用户的意图--
已经被过滤掉了。
$ getopt -o a:,b -- -a 1 -b pos1 pos2 -- fwd1
-a '1' -b -- 'pos1' 'pos2' 'fwd1'
将我的位置参数与转发的位置参数区分开来的最佳方法是什么?
我遇到过这样的问题:人们通过 ssh 登录某些服务器,却忘记特定终端不再是本地的。今天,有人尝试使用 关闭笔记本电脑sudo shutdown -h now
,并意外地关闭了服务器。
我想PS1
在通过 登录时更改这些服务器上bash 的颜色ssh
。我通过推送给它们的 debian 软件包来控制这些服务器。
推动全站 PS1 默认设置的最佳方式是什么?
显而易见的答案是创建一个/etc/profile.d/sshcolours
包含以下内容的文件,以使 user@host 变为紫色:
if [ -n "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ] ; then
PS1='\[\033[01;35m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
fi
bash
/etc/profile
将通过(来源)阅读该内容/etc/profile.d/*
。但是,它稍后会读取~/.bashrc
,这可能会PS1
根据$TERM
中的定义进行覆盖/etc/skel/.bashrc
。
有没有什么方法可以让我在不接触并且不强迫我的团队采用客户端更改的情况source
下进行站点范围的文件?~/.bashrc
~/.bashrc
这里有一些不好的想法:
设置后$PS1
,~/.bashrc
有条件地来源/usr/share/bash-completion/completions/*
,这样我就可以把我的文件放在那里。但一些测试表明,条件不满足,或者/usr/share/bash-completion/bash_completion
恢复了环境。
我postinst
可以附加一行将我的文件源到每个用户的~/.bashrc
. 这感觉既非法又有问题:
for h in /home/*; do
if [ ! grep -q profile_amendments "$h/.bashrc" ] ; then
echo ". /etc/profile_amendments" >> "$h/.bashrc"
fi
done
我想使用 来监视文件inotify
,并在有人更改内容(IN_MODIFY
或)时触发一些代码,但是当用户使用他们喜欢的工具编辑文件时,IN_CLOSE_WRITE
我遇到了停止返回事件的问题。inotify
该文件应该很简单(单行、无空格、最多 20 个字符)。我不想限制它们的使用,但我不确定如何处理不同的情况。
我正在使用inotify
这些是当各种应用程序编辑文件时我收到的事件:
行动 | inotify 事件 |
---|---|
touch file |
IN_OPEN |
echo "data" > file |
IN_MODIFY ,IN_OPEN ,IN_ACCESS , 然后IN_CLOSE_NOWRITE |
nano file (打开时) |
IN_OPEN |
nano file (在^O ) |
IN_MODIFY , IN_CLOSE_WRITE , IN_OPEN ,IN_ACCESS |
vim file (打开时) |
IN_OPEN ,IN_CLOSE_NOWRITE |
vim file (在:w ) |
IN_MOVE_SELF , IN_ATTRIB , 然后事件停止来自该文件 |
gedit file (打开时) |
IN_OPEN , IN_CLOSE_NOWRITE ,IN_ACCESS |
gedit file (保存时) |
IN_OPEN , IN_CLOSE_WRITE , IN_ATTRIB ,然后事件停止来自该文件 |
mv newfile file |
IN_ATTRIB ,然后事件停止来自该文件 |
有一次,我以为我看到了gedit
触发器,IN_DELETE_SELF
然后又沉默了。
vim
在用户使用and的情况下gedit
,我会inotify
在用户完成编辑后停止获取事件。我该如何处理这个问题?
我所看到的唯一共同点是事件IN_ATTRIB
。我怀疑当我收到事件时IN_ATTRIB
,我应该inotify_rm_watch()
这样做,然后基于相同的路径wd
重新创建一个新的。inotify_add_watch()
但这是正确的方法吗?
另一种选择可能是监视父目录。受影响的文件名包含在 中inotify_event::name
,因此我可以过滤感兴趣的文件,并触发任何IN_MODIFY
与我感兴趣的文件匹配的IN_CLOSE_WRITE
位置。name
我正在将 bash-completion 添加到现有工具中。
在有人传递-s
标志后,我想提供几个关于 bash-completion 的选项:
Closed
Feedback
"In Progress"
New
Rejected
Resolved
里面的空间"In Progress"
引起了问题。
#!/usr/bin/env bash
_remote-redmine()
{
local cur
COMPREPLY=()
cur=${COMP_WORDS[$COMP_CWORD]}
case "${COMP_WORDS[($COMP_CWORD-1)]}" in
-s)
s_opts=( "New" "In Progress" "Resolved" "Feedback" "Closed" "Rejected" )
COMPREPLY=( $( compgen -W "${s_opts[*]}" -- "$cur") )
;;
esac
return 0
}
complete -F _remote-redmine remote-redmine
当我运行该工具时,我得到:
$ remote-redmine -s <tab><tab>
Closed Feedback In New Progress Rejected Resolved
但我想得到:
$ remote-redmine -s <tab><tab>
Closed Feedback "In Progress" New Rejected Resolved
或者
$ remote-redmine -s <tab><tab>
Closed Feedback In\ Progress New Rejected Resolved
我尝试过的事情:
s_opts=( ... "In\ Progress" ... )
: 没有不同
s_opts( ... "In\\ Progress" ...)
: 没有不同
s_opts( ... "In\\\ Progress" ...)
: 两个选项是In\
和Progress
s_opts( ... "\"In Progress\"" ...)
: 没有不同
compgen -o nospace ...
: 没有不同
compgen -o noquote ...
: 没有不同
至少compgen
可以放In Progress
一行,但这并不能转化为complete
$ compgen -W 'New "In Progress"'
New
In Progress
转义额外的引号有助于compgen
,但这并不能转化为complete
:
$ compgen -W 'New "\"In Progress\""'
New
"In Progress"
转义空格三次确实有帮助,但仍然没有帮助;不能转化为complete
:
$ compgen -W 'New In\\\ Progress'
New
In\ Progress
我认为逃离该空间七次是有希望的,因为这样complete
可以解决其中的一些问题,但这也没有帮助:
$ compgen -W 'New In\\\\\\\ Progress'
New
In\\\ Progress
...
$ remote-redmine -s <tab><tab>
... In\\\ New Progress ...
绕过compgen
会起作用,但随后我会失去单选项卡上的自动填充和双选项卡上的过滤功能
COMPREPLY=( ... 'In\ Progress' ... )
COMPREPLY=( ,,, '"In Progress"' ... )
我有一个正在签署的许可证:
gpg --default-sig-expire "2024-02-14" --sign licence
这导致:
$ gpg --verify licence.gpg
gpg: Signature made Tue 13 Feb 2024 08:18:39 AM CET
gpg: using RSA key 1234567890ABCDEF1234567890ABCDEF
gpg: issuer "[email protected]"
gpg: Good signature from "Stewart <[email protected]>" [ultimate]
gpg: Signature expires Wed 14 Feb 2024 12:00:00 PM CET
这12:00:00 PM CET
是我的问题。我通常那个时候去吃午饭。我不想在午餐时接到有关系统离线的电话。可以指定时间吗?我宁愿它过期于13:00:00 PM CET
。
--ask-sig-expire
仅提示您输入天数/周数/年数:
$ gpg --ask-sig-expire --sign licence
Please specify how long the signature should be valid.
0 = signature does not expire
<n> = signature expires in n days
<n>w = signature expires in n weeks
<n>m = signature expires in n months
<n>y = signature expires in n years
Signature is valid for? (0)
ISO 8601 似乎不受支持:
$ gpg --default-sig-expore "2024-02-14T13:00:00+02:00" --sign licence
gpg: '2024-02-14T13:00:00+02:00' is not a valid signature expiration
该man systemd.time
规范似乎不受支持
$ gpg --default-sig-expire "2024-02-14 13:00:00" --sign licence
gpg: '2024-02-14 13:00:00' is not a valid signature expiration
手册页也没有表明可能的时间:
--default-sig-expire
The default expiration time to use for signature expiration. Valid values
are "0" for no expiration, a number followed by the letter d (for days),
w (for weeks), m (for months), or y (for years) (for example "2m" for two
months, or "5y" for five years), or an absolute date in the form
YYYY-MM-DD. Defaults to "0".
我找到的唯一解决方案是将系统的时区更改为我以西的下一个时区,然后签名,然后将系统的时区设置回原来的时间。
$ sudo mv /etc/localtime{,.backup}
$ sudo ln -s /usr/share/zoneinfo/Europe/London /etc/localtime
$ gpg --default-sig-expire "2024-02-14" --sign licence
$ sudo mv /etc/localtime{.backup,}
$ gpg --verify licence.gpg
gpg: Signature made Tue 13 Feb 2024 08:18:39 AM CET
gpg: using RSA key 1234567890ABCDEF1234567890ABCDEF
gpg: issuer "[email protected]"
gpg: Good signature from "Stewart <[email protected]>" [ultimate]
gpg: Signature expires Wed 14 Feb 2024 01:00:05 PM CET
我们有一个私有证书颁发机构 (CA),仅在我们的 Intranet 站点上使用。
我可以轻松获得证书:
openssl s_client -showcerts -connect atlas.sim.local:8443 </dev/null 2>/dev/null|openssl x509 -outform PEM >atlas.crt
我希望我的 Debian 设备自动信任此证书颁发机构。我有私人apt
存储库,并且我的所有 debian 设备都安装了此存储库中的软件包。因此,我希望将此*.crt
文件部署到此包中。
该包将有效地做到这一点:
install -Dm644 atlas.crt /usr/share/ca-certificates/sim.local/atlas.crt
但是,部署此文件后如何重新生成 ca 证书?我正在寻找要部署的文件或可以在其中运行的行postinst
。
我的第一个想法很简单:
/usr/sbin/update-ca-certificates
但man update-ca-certificates
说:
update-ca-certificates
是一个更新目录/etc/ssl/certs
以保存 SSL 证书并生成ca-certificates.crt
...的程序它读取文件
/etc/ca-certificates.conf
。/usr/share/ca-certificates
每行给出了应信任的CA 证书的路径名。
为此,我需要确保sim.local/atlas.crt
位于/etc/ca-certificates.conf
. 不幸的是,没有任何/etc/ca-certificates.conf.d/
东西可以让我插入包含该内容的另一个文件。
如果我读/etc/ca-certificates.conf
,它说:
# This file lists certificates that you wish to use or to ignore to be
# installed in /etc/ssl/certs.
# update-ca-certificates(8) will update /etc/ssl/certs by reading this file.
#
# This is autogenerated by dpkg-reconfigure ca-certificates.
因此,我可以尝试:
dpkg-reconfigure ca-certificates
但这会导致出现一个交互式对话框,默认情况下取消选择我的证书。我宁愿这是非交互式的。
这是我目前的postinst
。但我不确定这是否是正确的解决方案。有正确的方法吗?
#!/bin/bash
set -e
case "$1" in
configure)
if [ -e /etc/ca-certificates.conf ] &&
! grep -q sim.local/atlas.crt /etc/ca-certificates.conf; then
printf "%s\n" sim.local/atlas.crt >> /etc/ca-certificates.conf;
/usr/sbin/update-ca-certificates;
fi
;;
esac
我的机器上有这个:
$ cat /etc/profile.d/proxy.sh
export http_proxy=http://192.168.1.30:3128
export https_proxy=https://192.168.1.30:3128
效果很好,直到我需要对本地主机上的应用程序使用 HTTP 接口。
$ wget localhost
--2023-03-02 06:54:52-- http://localhost/
Connecting to 192.168.1.30:3128... connected.
Proxy request sent, awaiting response... 503 Service Unavailable
2023-03-02 06:54:52 ERROR 503: Service Unavailable.
$ wget 127.0.0.1
--2023-03-02 06:55:20-- http://127.0.0.1/
Connecting to 192.168.1.30:3128... connected.
Proxy request sent, awaiting response... 403 Forbidden
2023-03-02 06:55:20 ERROR 403: Forbidden.
有没有办法阻止localhost
和127.0.0.1
请求被转发到代理?
细节:
这台机器没有直接连接到互联网。它没有网关或默认路由。但它位于带有代理服务器 (192.168.1.30) 的 LAN 上,该代理计算机 (192.168.1.30) 安装了代理服务器(端口 3128)并具有 Internet 连接。
$ ip addr
1: lo: ...
inet 127.0.0.1/8 scope host lo
2: eno1: ...
altname enp24s0f0
inet 192.168.1.100/24 brd 192.168.1.255 scope global eno1
$ ip route
192.168.1.0/24 dev eno1 proto kernel scope link src 192.168.1.100
$ cat /etc/hosts
127.0.0.1 localhost
$ cat /etc/network/interfaces
auto lo
iface lo inet loopback
auto eno1
iface eno1 inet static
address 192.168.1.100
netmask 255.255.255.0
我想从一个*.deb
包中安装一个服务,使用update-alternatives
. 然后启用/启动符号链接。在现有的 debian 档案中有这样的例子吗?如果没有,人们将如何做到这一点?
我这样做是因为我希望能够在同一台机器上部署我的软件的多个版本,然后使用update-alternatives
来选择运行哪个版本。
update-alternatives
对于使用并依赖 debhelper 提供服务的东西,典型的控制文件可能如下所示:
# myapp99.postinst
update-alternatives --install \
/lib/systemd/system/myapp.service myapp \
/lib/systemd/system/myapp99.service 99
#DEBHELPER#
# myapp99.prerm
update-alternatives --remove myapp lib/systemd/system/myapp99.service
#DEBHELPER#
但是这里的问题是在我已经完成它之后#DEBHELPER#
会继续运行。myapp.service
postrm
update-alternatives --remove
我可以在 postrm 中将我的update-alternatives --remove
移到#DEBHELPER#
after ,但我仍然会遇到一个问题,即清除旧的未使用的包将 stop/disable myapp.service
。我敢肯定还有其他事情我也没有考虑。
现有的 debian 存档中是否有任何软件包可以做我想做的事情?
我几乎考虑不这样做debhelper
:在安装之前检查链接是否存在,如果是新的则启用。清除后检查链接是否存在,仅当这是该服务的最后一个供应商时才停止/禁用/屏蔽。如果这是唯一的方法,那很好......我只是不想重新发明轮子并引入错误。
我正在尝试连接到二手外部 wifi 摄像头。它有一个以太网插槽和一个带有 MAC 地址但没有其他品牌或型号/序列号的标签。
我正在尝试查找它的 IP 地址。
我目前的计划是在我的机器和这台相机之间直接连接一根以太网电缆,然后使用以下命令扫描所有保留的私有 IPv4 范围nmap
:
ip addr add 10.0.0.1/8 dev eno2
ip addr add 172.16.0.1/12 dev eno2
ip addr add 192.168.0.1/16 dev eno2
nmap -sn 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
但这可能需要很长时间(我猜大约需要 74 小时),而且我不能确定这个设备没有使用 IPv6。有更好的解决方案吗?
我有一个 GUI,可以在其中显示ActiveState
几个 systemd 服务。
在 10Hz 时,我使用 sd-bus api 来查询每个服务,如下所示:
sd_bus* bus;
sd_bus_error err = SD_BUS_ERROR_NULL;
char* msg = 0;
sd_bus_default_system(&bus);
sd_bus_get_property_string(bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1/unit/foo_2eservice",
"org.freedesktop.systemd1.Unit",
"ActiveState",
&err,
&msg);
我的问题是,当我运行这段代码时,/sbin/init
还是/lib/systemd/systemd-logind
消耗了大约 50% 的 CPU。分析代码显示sd_bus_get_property_string
. 我需要减少调用此函数的次数。
d-bus接口的自省很有意思:
busctl introspect \
org.freedesktop.systemd1 \
/org/freedesktop/systemd1/unit/foo_2eservice \
org.freedesktop.system1.Unit
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.Kill method si - -
.Ref method - - -
.Reload method s o -
.ReloadOrRestart method s o -
.ReloadOrTryRestart method s o -
.ResetFailed method - - -
.Restart method s o -
.SetProperties method ba(sv) - -
.Start method s o -
.Stop method s o -
.TryRestart method s o -
.Unref method - - -
.ActiveEnterTimestamp property t 0 emits-change
.ActiveEnterTimestampMonotonic property t 0 emits-change
.ActiveExitTimestamp property t 0 emits-change
.ActiveExitTimestampMonotonic property t 0 emits-change
.ActiveState property s "inactive" emits-change
...
这告诉我 ActiveState 属性发出了一个 change。
如何获取文件描述符,或点击事件循环以接收该更改?
D-Bus 规范建议 systemd 将在属性更改时发出信号org.freedesktop.DBus.Properties.PropertiesChanged
。我想我需要弄清楚如何订阅该信号。
我正在尝试清理崩溃后服务留下的一些垃圾共享内存文件。该服务以系统用户和特定组的身份运行。我是该组的成员,但无法删除共享内存。
$ ls -la /dev/shm
drwxrwxrwt 2 root root 600 Jun 20 11:18 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 simbot simusers 500032 Jun 20 10:35 Sim_SharedMem_SLM__data_0
$ groups | grep simusers -q && echo member || echo not member
member
$ rm -f /dev/shm/Sim_SharedMem_SLM__data_0
rm: cannot remove '/dev/shm/Sim_SharedMem_SLM__data_0': Operation not permitted
我以root身份删除文件没有问题。如果我是运行(并导致崩溃)进程的人(我是拥有文件的用户),我删除文件也没有问题。
我认为展示问题的最简单方法是以我自己的身份运行该进程,然后更改一些垃圾文件,就好像它们归其他用户所有一样。
$ /usr/local/bin/badProcess
^C
$ ls -la /dev/shm
drwxrwxrwt 2 root root 640 Jun 20 11:31 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_0
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_1
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_2
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_3
$ sudo chown simbot Sim_SharedMem_SLM__data_1
$ sudo chown :simusers Sim_SharedMem_SLM__data_2
$ sudo chown simbot:simusers Sim_SharedMem_SLM__data_3
$ ls -la /dev/shm
drwxrwxrwt 2 root root 640 Jun 20 11:31 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_0
-rw-rw-rw- 1 simbot stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_1
-rw-rw-rw- 1 stew simusers 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_2
-rw-rw-rw- 1 simbot simusers 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_3
$ rm /dev/shm/*
rm: cannot remove 'Sim_SharedMem_SLM__data_1`': Operation not permitted
rm: cannot remove 'Sim_SharedMem_SLM__data_3`': Operation not permitted
一些解决方案建议使用 lsattr 检查 +a 或 +i 属性。
$ lsattr Sim_SharedMem_SLM__data_0
lsattr: Inappropriate ioctl for device While reading flags on Sim_SharedMem_SLM__data_0
发生这种情况是因为 tmpfs 不支持这些属性(这就是这个目录)
$ mount | grep /dev/shm
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
我查看了 ACL,看看父目录或文件本身是否有什么有趣的地方。我没有看到我们没有从中学到ls
我对父目录有写权限
$ getfacl /dev/shm
getfacl: Removing leading '/' from absolute path names
# file: dev/shm
# owner: root
# group: root
# flags: --t
user::rwx
group::rwx
other::rwx
$ getfacl /dev/shm/Sim_SharedMem_SLM__data_0
getfacl: Removing leading '/' from absolute path names
# file: dev/shm/Sim_SharedMem_SLM__data_0
# owner: simbot
# group: simusers
user::rw-
group::rw-
other::rw-
我有一个使用 cmake 的上游源包,我想将它打包为两个二进制 debian 包。
$ tree proj
proj/
├── app1.c
├── app2.c
└── CMakeLists.txt
Upstream 的CMakeLists.txt
写作已经考虑到了这一点。他们使用 COMPONENTS 参数install
$ cat proj/CMakeLists.txt
include(GnuInstallDirs)
add_executable(app1 app1.c)
install(
TARGETS app1
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT app1)
add_executable(app2 app2.c)
install(
TARGETS app2
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT app2)
要在本地编译/安装,非常简单:
$ mkdir build && cd build
$ cmake ../proj -DCMAKE_INSTALL_PREFIX=/usr/local # Configure
$ cmake --build . # Build
$ cmake -DCOMPONENT=app1 -P cmake_install.cmake # Install app1 component
$ cmake -DCOMPONENT=app2 -P cmake_install.cmake # Install app2 component
但是您将如何为此构建debian/rules
文件?
如何授予阅读somegroup
系统日志的只读权限?(我在 Debian10 buster 上)。
$ journalctl
Hint: You are currently not seeing messages from other users and the system.
Users in the 'systemd-journal' group can see all messages. Pass -q to
turn off this notice.
No journal files were opened due to insufficient permissions.
我知道我可以将用户添加到systemd-journal
组中,但是如何授予组读取权限?
我有一个看起来像这样的脚本:
#!/bin/bash
set -e
tmpdir=$(mktemp -d)
pushd $tmpdir
trap 'popd && rm -rf $tmpdir' EXIT
# Business logic which may succeed or fail...
/bin/false
当它退出时,它popd
很好,但它不会删除临时目录。陷阱中似乎$tmpdir
没有解决,但我们如何克服呢?
我通过在$tmpdir
没有. 退出时:-rf
rm
rm: missing operand
而不是预期的
rm: cannot remove '/tmp/tmp.Y1SdoY5dSu/': Is a directory
我正在尝试允许 a 的用户somegroup
管理someunit
systemd 服务。
在polkit (>=0.106)
中,这可以通过添加规则来完成:
/etc/polkit-1/rules.d/20-someunit.rules
---
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.manage-units"
&& subject.isInGroup("somegroup")
&& (action.lookup("unit") == "someunit.service") )
{
var verb = action.lookup("verb");
if (verb == "start" || verb == "stop" || verb == "restart") {
return polkit.Result.YES;
}
}
});
但是,我polkit 0.105
自 2012 年以来一直在使用 Debian stretch/buster。polkit(<0.106)
不支持这些rules.d/*
文件。相反,我们依赖/etc/polkit-1/localauthority/50-local.d/*.pkla
.
按照pklocalauthority(8)中的一些示例,我可以在等效的 pkla 文件中完成大部分工作:
/etc/polkit-1/localauthority/50-local.d/manage-units.pkla
----
[Allow users to manage services]
Identity=unix-group:somegroup
Action=org.freedesktop.systemd1.manage-units
ResultActive=yes
但是,这会授予对所有服务的所有操作的访问权限。是否有等效于允许特定action.lookup()
功能的方法?
我确实尝试过systemctl enable
and systemctl edit
,但都失败了(这很好)。所以action.lookup("verb")
可能不是必需的,但action.lookup("unit")
仍然非常重要。
关于这个主题有很多悬而未决的问题:
我希望组foogroup
中的用户能够:
systemctl start foo.service
,systemctl stop foo.service
,systemctl status foo.service
, 和journalctl -u foo.service
不使用提升的权限。那可能吗?
我有一个 systemd 服务,它看起来像:
[Unit]
Description=foo service
[Service]
Type=simple
ExecStart=/bin/sleep infinity
User=foobot
Group=foogroup
foobot
系统用户在哪里。
我知道我们可以安装单元文件以~/.config/systemd/user/
允许非特权用户使用 systemd,但这并不能真正帮助一个组。
注意:我计划使用sd-bus API from libsystem-dev
and cockpit,所以添加systemctl
到/etc/sudoers
不会有帮助。
我不太在乎systemctl enable
,如果我需要提升特权也没关系。
我正在创建一个foo
启动/关闭上游包的包bar
。关系应该是:
bar
可以在不影响的情况下启动、停止或重新加载foo
如果/lib/systemd/system/bar.service
看起来像这样:
[Unit]
Description=Bar
[Service]
ExecStart=/bin/sleep infinity
Restart=on-failure
然后“正常”的解决方案是添加WantedBy
和PartOf
关系bar
:
[Unit]
Description=Bar
PartOf=foo.service
[Service]
ExecStart=/bin/sleep infinity
Restart=on-failure
[Install]
WantedBy=foo.service
但是,bar
它是一个上游包,我认为强制bar
了解foo
或修补bar
.
我认为一个完美的解决方案是这样创建foo.service
:
[Unit]
Description=Foo
Wants=bar.service
ConsistsOf=bar.service
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
但是我的 journalctl 说:
“单元”部分中的未知左值“ConsistsOf”
手册页说:
当在 a.service 上使用 PartOf=b.service 时,此依赖关系将在 b.service 的属性列表中显示为 ConsistsOf=a.service。ConsistsOf= 依赖项不能直接指定。
我不确定为什么 ConsistsOf=
不能直接指定,但有没有我没有考虑过的替代方案?