我运行iotop以检查重度磁盘用户的程序,以防我需要降低它们的优先级。通常这已经足够了,但iotop只显示线程 ID (TID),有时我想知道进程 ID (PID),以便我可以找到有关哪个进程负责的更多信息。
不幸的是,虽然ps可以显示 TID(又名 SPID,LWP),但它没有一个标志来获取 TID 列表,就像处理带有--pid. 我能做的最好的事情就是列出 TID,然后grep是输出。例如,如果线程 id 是 792,我可以这样做
$ ps -eLf | grep ' 792 '
Run Code Online (Sandbox Code Playgroud)
这工作得相当好,但有点不优雅。
有没有更好的办法?
考虑这个脚本。
#! /usr/bin/env bash
mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file
ln --symbolic mydir mylink
file mylink
stow --verbose --dir=./mylink --target=./target package
file target/file
Run Code Online (Sandbox Code Playgroud)
输出是
mylink: symbolic link to mydir
LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file
Run Code Online (Sandbox Code Playgroud)
在运行之前stow,它看起来像这样:
.
??? mydir
? ??? package
? ??? file
??? mylink -> mydir
??? target
Run Code Online (Sandbox Code Playgroud)
运行stow, on 后mylink,我希望它看起来像这样:
.
??? mydir
? ??? package
? ??? file
??? mylink -> mydir
??? target …Run Code Online (Sandbox Code Playgroud) 我可以运行strace类似的命令sleep 1
并查看它正在访问哪些文件,如下所示:
strace -e trace=file -o strace.log sleep 1
Run Code Online (Sandbox Code Playgroud)
然而,在我的机器上,许多调用的返回值为-1,表明该文件不存在。例如:
$ grep '= -1 ENOENT' strace.log | head
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.UTF-8/LC_MEASUREMENT", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file …Run Code Online (Sandbox Code Playgroud) 我正在尝试记录交互式命令行程序的输出;units, 具体来说。
我尝试过tee 这样使用:
units | tee units.log
Run Code Online (Sandbox Code Playgroud)
或这样的脚本:
script -c units units.log
Run Code Online (Sandbox Code Playgroud)
但它们都将所有退格键和制表符补全记录为特殊字符,如下所示:
You have: 55 horsepower ^G/^H^[[K^M
You want: wat^Gt ^M
* 41013.493^M
/ 2.438222e-05^M
Run Code Online (Sandbox Code Playgroud)
的联机帮助页script提到了这个问题。
错误
脚本将所有内容放入日志文件中,包括换行符和退格键。这不是天真的用户所期望的。
我知道使用cat和/more或剥离转义字符查看文件的解决方法col,如下所述:
以及这里的 perl 脚本:
http://log.guidoderosa.net/2009/05/another-old-post-which-may-be-useful.html
但我并不是特别想修复现有的日志文件:我想避免创建因删除的输入和控制字符而乱码的新日志文件。
我以为我已经使用 解决了问题rlwrap,但它与unitsreadline 功能冲突,因此它要么无法捕获输出,要么rlwrap -a捕获输出但否定units使用制表符完成的能力。rlwrap -a -N没有帮助。这在手册页中有详细记录:
错误和限制
尽管 rlwrap 很灵活,可以交付货物(readline 功能),并且遵循 Unix“许多小工具”范例,但它是一个拼凑品。它无法了解有关命令内部状态的任何信息,这使得上下文相关的完成变得不可能。在命令中使用 readline 库仍然是最好的选择。
有没有什么方法可以干净地记录交互式输入和输出,而又不会干扰现有readline功能?
更新:我会对类似的事情感到高兴
units | col -b …Run Code Online (Sandbox Code Playgroud) 有时我会在桌面通知中收到错误消息,例如:
不幸的是,很难调试它。我无法xprop查看发送它的进程 ID。它声称来自 VBoxClient,但我不能确定。我什至无法复制通知气泡中的文本。我能做的最好的就是截图。
是否有某种方法可以将桌面通知记录到/var/log/messages或以其他方式获取有关发送它的进程的信息,或者至少是通知本身的文本?
我希望当光标位于单词的开头和光标位于单词的末尾时,制表符完成的行为有所不同。
我只见过用制表符完成后缀的 shell,如下所示:
$ tiff2?
tiff2bw tiff2pdf tiff2ps tiff2rgba
Run Code Online (Sandbox Code Playgroud)
但是,有时我还想在插入符号位于单词开头时对前缀进行制表符补全。也就是说,2tiff
如果光标位于单词的开头,我想扩展到所有以 结尾的命令2tiff,如下所示:
$ ?2tiff
raw2tiff gif2tiff bmp2tiff ppm2tiff pnmtotiff ras2tiff e2mtiff fax2tiff
Run Code Online (Sandbox Code Playgroud)
Fish在某些情况下会这样做:
~> ?2tiff
bmp2tiff (Executable, 17kB) ppm2tiff (Executable, 14kB)
fax2tiff (Executable, 18kB) ras2tiff (Executable, 14kB)
gif2tiff (Executable, 18kB) raw2tiff (Executable, 17kB)
Run Code Online (Sandbox Code Playgroud)
这也有将光标移动到单词末尾的副作用,并且仅在没有有效的后缀完成时才有效:
~> ?tiff
tiff2bw (Convert a color TIFF image to greyscale)
tiff2pdf (Convert a TIFF image to a PDF document)
tiff2ps (Convert a TIFF image to)
tiff2rgba (Convert a TIFF image to RGBA …Run Code Online (Sandbox Code Playgroud) 我不明智地要求gdb列出所有定义的函数。
(gdb) info function
Run Code Online (Sandbox Code Playgroud)
现在它正在兴奋地占用 CPU 和内存。如果我真的很快,GDB 将停止使用 Ctrl-C 并再次提示我。
(gdb) info functions
^CQuit
(gdb)
Run Code Online (Sandbox Code Playgroud)
但是如果我太慢,它就不会响应 Ctrl-C (SIGINT)、Ctrl-\ (SIGQUIT) 或 SIGTERM。
(gdb) info functions
^C^C^\
Run Code Online (Sandbox Code Playgroud)
奇怪的是,GDB 确实响应了 SIGUSR1。
(gdb) info functions
^C^C^\User defined signal 1
Run Code Online (Sandbox Code Playgroud)
但是,这结束了我的 GDB 会话,我必须重新开始。是否有另一种方法可以停止不会完全杀死 GDB 的缓慢运行的命令?
作为记录,我在 Debian 9.3 (stretch) 上运行 GDB 版本 7.12.0.20161007-git。
我一直在使用 bash 的edit-and-execute-command功能:
edit-and-execute-command (C-x C-e)在当前命令行调用编辑器,并将结果作为 shell 命令执行。Bash 尝试按照编辑器的顺序调用
$VISUAL、$EDITOR和emacs。
https://www.gnu.org/software/bash/manual/html_node/Miscellaneous-Commands.html
我注意到如果我调用一个编辑器,使用 Ctrl-Z 把它放到后台,然后再用fg把它放回前台,shell 不再执行临时文件。
如果我想中止命令,这很方便,但我发现这种行为在第一次发生时有点令人惊讶。
我的问题:
为什么会发生这种情况?
我从edit_and_execute_command最终调用fc的源代码中知道,但我并不清楚
为什么发送 SIGTSTP 会阻止 bash 执行临时文件。
如果我不小心按了 Ctrl-Z 并且仍然想在编辑器仍然打开的临时文件中执行脚本,那么最好的方法是什么?
考虑这样的脚本:
$ cat example.sh
#! /usr/bin/env bash
for i in {1..90}
do
printf '%s\n' "$i"
done
sleep 10
printf '91\n'
sleep 10
printf 'done\n'
Run Code Online (Sandbox Code Playgroud)
并假设输出通过管道传输到更少,如下所示:
$ bash example.sh | less
Run Code Online (Sandbox Code Playgroud)
如果我向下滚动到第 90 行,我可以再次向上滚动、搜索和使用提供的任何其他交互式命令less。但是,一旦我尝试使用 eg jor越过第 90 行Ctrl-N,就会
less停止响应交互式命令,直到有另一行输入可用为止。如果我尝试使用空格键滚动整页超过第 90 行,则
less停止响应交互式命令,直到整页输入可用或收到 EOF。
如果我想查看以前的输出并且没有意识到我刚刚浏览了可用的行并且必须等待更多行出现,这可能是不可取的,这可能需要任意数量的时间。
如果我使用 Ctrl-C 发送 SIGINT,我可以立即再次获得交互性,但随后less将停止侦听来自管道的更多输入。
该脚本只是一个易于重现的示例,但它可以被任何长时间运行的缓慢生成输出行的命令替换,例如查找损坏的符号链接:
$ find $HOME -xtype l | less
Run Code Online (Sandbox Code Playgroud)
或我的主目录中的世界可读权限:
$ find $HOME -perm 777 | less
Run Code Online (Sandbox Code Playgroud)
或任何其他将行发送到stdout.
有什么方法可以让我less停止等待更多输入并重新获得交互式命令,而无需等待从管道中生成所需的输入行?
我可以将 sudo 会话的状态添加到 bash 提示符中,如下所示:
function sudo_active() {
if sudo -n /bin/true 2> /dev/null
then
printf '(sudo) '
fi
}
PS1="$PS1"'$(sudo_active)'
Run Code Online (Sandbox Code Playgroud)
这样我就可以运行一系列 sudo 命令,然后我就会知道 sudo 会话是否仍然处于活动状态。我可以使用 提前结束会话sudo -k、关闭 shell,或者只是记住要小心。
这种方法的一个问题是,每次在没有 sudo 权限的情况下运行新提示时,它都会在系统日志中添加如下消息:
sudo[25653]: myusername : a password is required ; TTY=pts/13 ; PWD=/home/myusername/ ; USER=root ; COMMAND=/bin/true
Run Code Online (Sandbox Code Playgroud)
另一个问题是,因为这sudo每次都会在提示符中运行命令,所以每次运行命令时(取决于 的值),它都会重新延长超时passwd_timeout,即使我不运行需要 的命令sudo。
有没有办法可以测试 sudo 会话是否仍然处于活动状态并在 bash 提示符中显示这一点,而不会不断重新扩展会话作为副作用?
bash ×3
signals ×3
readline ×2
autocomplete ×1
d-bus ×1
fc ×1
fish ×1
freedesktop ×1
gdb ×1
less ×1
libnotify ×1
line-editor ×1
logs ×1
pager ×1
pipe ×1
prompt ×1
ps ×1
pthreads ×1
sigint ×1
stdin ×1
stow ×1
strace ×1
sudo ×1
symlink ×1
system-calls ×1
tee ×1
terminal ×1
thread ×1
units ×1
zsh ×1