我正在使用 PuTTY (0.82) 与 Linux 系统进行 SSH 会话。
使用“可打印输出”选项来开启日志记录。
如果我在 SSH 窗口(bash)中使用命令制表符完成,此操作也会记录到日志文件中,这使得之后很难读取日志中发出的命令。
有没有什么办法可以避免这种情况?
我尝试了日志选项“可打印输出”和“所有会话输出”,但都没有提供预期的结果。我是否错过了其他选项?
我正在使用 PuTTY (0.82) 与 Linux 系统进行 SSH 会话。
使用“可打印输出”选项来开启日志记录。
如果我在 SSH 窗口(bash)中使用命令制表符完成,此操作也会记录到日志文件中,这使得之后很难读取日志中发出的命令。
有没有什么办法可以避免这种情况?
我尝试了日志选项“可打印输出”和“所有会话输出”,但都没有提供预期的结果。我是否错过了其他选项?
>(cmd)
是 Bash 语法。例如,
$ echo 42 > >(cat)
42
效果很好。
因此,我希望使用这种方法将新编辑和保存的文件作为另一个命令的输入(我只是用作cat
示例):
$ EDITOR=nano # or emacs, vi, ...
$ $EDITOR >(cat)
然后它就冻结了。为什么?
在安装服务器时,我安装了 neofetch,就像其他人一样。每当我登录到 shell 时,我都会运行它。
快进到今天,我已经卸载了 neofetch 而使用 fastfetch。
现在,当我登录时,我在终端顶部收到一条可爱的错误消息:
-bash: neofetch: command not found
好的,我期望如此。但是,我无论如何也找不到需要从哪里删除调用。
它不在.bashrc
、 或 中.profile
。哎呀,我甚至在文件系统上尝试了递归 grep(见下文)来查找neofetch
,结果返回了…… 0 个匹配项。它也不是 SSHRemoteCommand
设置,因为它发生在使用不同配置的多个客户端上。
如果相关的话,我正在使用 tmux 来实现终端持久性。
显然,重新安装 Debian 超出了范围,我想我可以忽略它,但这很烦人。
我很清楚第一世界的问题有多严重。
Grep 命令:
sudo grep -Rnwso / -e 'neofetch'
这将返回一些来自.bash_history
neofetchconfig.conf
文件的结果,但是不会有任何结果会导致 neofetch 在登录时运行。
我希望每个 VSCode 工作区都有不同的 bash 历史记录。似乎设置:
"terminal.integrated.env.linux": { "HISTFILE": "${workspaceFolder}/.bash_history" ...
会非常危险。
... 迟早你会在公开的存档或存储库中泄露一些机密命令。在多用户计算机上,只要你切换到另一个用户的目录并在那里运行一些命令,他们就可以修改你的文件,并可能获得你帐户的后门。而其他用户或你下载存档的人可以通过将命令注入你的 shell 历史记录中,轻松地诱骗你运行命令。
– Gilles ‘所以,别再作恶了’ 评论于 2016 年 8 月 24 日 23:15
即将历史记录保存到您的工作区是不好的,因为您将使用秘密(密码,密钥等)运行命令,并且您会在某个时候将您的历史记录泄露到目录 tar 或 docker 镜像中,即使它在您的 git ignore 中。
我发现的一种方法:
[更新]感谢大家迄今为止的评论和想法。基于这些,我更新并扩展了原始问题,添加了更多信息和示例。
我们假设目前没有实际用例,唯一的目标是了解这是否可能,如果可能,如何实现。
我想运行一个脚本并确定它是直接由用户运行还是在另一个脚本中调用。我还想检查它是否有来源。
这意味着有 4 个主要测试用例:
我的大脑已经非常生疏,谷歌和 ChatGPT 为我提供了一系列检查,以测试它们是否在终端中运行,但没有一个能够在所有 4 个调用中给出正确的结果。
测试已完成check-term
并且有一个调用脚本check-term-driver
,均在下面。
如果我按照上面给出的顺序运行 4 个测试用例,对于给定的正确测试号(假设测试号为 n),我希望输出为:
n: in terminal: not sourced: ...
n: in terminal: sourced: ...
n: not in terminal: not sourced: ...
n: not in terminal: sourced: ...
在所有 4 个调用中,对是否存在来源的测试都是正确的。
检查项脚本:
#!/usr/bin/env bash
IS_TERMINAL=true
NOT_TERMINAL=false
TEST_NUM=0
SOURCED_TEXT="undefined"
print_result() {
TEST_NUM=$((TEST_NUM + 1))
if [ "$1" = "$IS_TERMINAL" ]; then
printf "%2d: %-16s %-12s %s\n" "$TEST_NUM" "in terminal:" "$SOURCED_TEXT:" "$2"
else
printf "%2d: %-16s %-12s %s\n" "$TEST_NUM" "not in terminal:" "$SOURCED_TEXT:" "$2"
fi
}
# First check if script is sourced or not.
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
SOURCED_TEXT="not sourced"
else
SOURCED_TEXT="sourced"
fi
# Tests run individually in expanded if/else for clarity.
# - test condition described by the result text.
if [ -t 0 ]; then
print_result "$IS_TERMINAL" "stdin is a terminal"
else
print_result "$NOT_TERMINAL" "stdin is not a terminal"
fi
if [ -t 1 ]; then
print_result "$IS_TERMINAL" "stdout is a terminal"
else
print_result "$NOT_TERMINAL" "stdout is not a terminal"
fi
if [ -t 2 ]; then
print_result "$IS_TERMINAL" "stderr is a terminal"
else
print_result "$NOT_TERMINAL" "stderr is not a terminal"
fi
if [[ "$-" == *i* ]]; then
print_result "$IS_TERMINAL" "interactive shell"
else
print_result "$NOT_TERMINAL" "non-interactive shell"
fi
if [ -n "$(tty)" ]; then
print_result "$IS_TERMINAL" "has a controlling terminal"
else
print_result "$NOT_TERMINAL" "does not have a controlling terminal"
fi
if [ -p /dev/stdin ]; then
print_result "$NOT_TERMINAL" "running in a pipeline"
else
print_result "$IS_TERMINAL" "not running in a pipeline"
fi
if [ -z "$(jobs -p)" ]; then
print_result "$IS_TERMINAL" "running in foreground"
else
print_result "$NOT_TERMINAL" "running in background"
fi
# Get ID of process that started the script.
PPID_VALUE=$(ps -o ppid= -p $$ | awk 'NR==2 {print $1}')
# If ID can't be found, give it a default value.
[ -z "$PPID_VALUE" ] && PPID_VALUE=1
# Check if attached or not.
if [ "$PPID_VALUE" -ne 1 ]; then
print_result "$IS_TERMINAL" "attached to a parent process"
else
print_result "$NOT_TERMINAL" "detached from a parent process"
fi
# Check if the parent process is a shell
PARENT_CMD=$(ps -o args= -p "$PPID_VALUE" 2>/dev/null)
if echo "$PARENT_CMD" | grep -qE '/(bash|zsh|sh)(\s|$)'; then
print_result "$IS_TERMINAL" "parent process is a shell"
else
print_result "$NOT_TERMINAL" "parent process is not a shell"
fi
驱动脚本:
#!/usr/bin/env bash
./check-term
echo ""
. ./check-term
我尝试使用 bash 将 mp4 文件转换为 mp3:
IFS=$'\n'
for f in $(ls -1 --quoting-style=escape -R ./*.mp4); do ffmpeg -i "$f" "${f%.mp4}.mp3"; done
并且,ffmpeg 抛出一个错误:./Asu\ no\ Yozora\ Shoukaihan.mp4: No such file or directory
但是如果我尝试手动输入它,它会正常工作,有人知道它为什么会这样吗?
虽然我的所有 RHEL 服务器在启动新的“终端”或“konsole”(基本上执行“~/.bashrc”和“/etc/profile.d/...”脚本)时都使用“bash -l”作为默认值,但我没有在 Ubuntu20LTS 服务器中进行此项配置。
我想在为所有用户打开新的“终端”或“konsole”窗口时自动执行“/etc/profile.d/...”脚本。
但在 Ubuntu20LTS 中情况并非如此。我总是必须在新的“终端/konsole”中执行“bash -l”才能从“/etc/profile.d/..”加载正确的环境设置。
我如何更改 Ubuntu20LTS 默认设置,即“终端/konsole”默认启动“bash -l”?
我感觉当我输入git add
->时Tab它只会提供有意义的文件 - 即未跟踪或修改的文件。
无论如何,现在相当长一段时间它都会列出每个文件。
我进行了一些研究,发现/usr/share/bash-completion/completions/git
我认为它具有我想要的功能。知道为什么它可能无法正常工作吗?
使用 CentOS Stream 9 和 git 2.43.5
find ..
我知道当您由于“奇怪”的文件名而遇到将例如输出管道传输到的问题时,使用特定的分隔符(例如)来实际传递完整的文件名(例如)xargs
会有所帮助。并且,引用有问题的字符串以指定它们的边界“总是”有帮助的。\0
find foldername/ -type f -print0 | xargs -0 ...
但是,如果这些字符串(文件名)包含 bash 敏感字符'
(如,,,,,"
.. ?)并且您想使用一个字符串两次(即必须使用,并且需要在嵌套命令中注入这些字符串(即)?`
(
sh -c ..
$(CMD)
例如:
# create a file which should not exist but does
mkdir remove_afterwards
touch remove_afterwards/"some [\"strange\"] ('file')"
# this will work
find remove_afterwards/ -type f -print0 | xargs -0 -I{} sh -c 'echo "{}"'
# but this won't due to the nested command
find remove_afterwards/ -type f -print0 | xargs -0 -I{} sh -c 'echo "{}" $(stat -c "%s" "{}")'
stat: cannot statx 'remove_afterwards/some [strange] ('\''file'\'')': No such file or directory
remove_afterwards/some [strange] ('file')
我还没弄清楚如何逃离第二个{}
里面$()
。
有办法吗?
不可否认,一些具有功能的真实脚本会使这一切更容易编写和阅读,但我很好奇,历史上有这样一行代码值得努力去写这个问题。
我知道我可以输入 exit、logout 或点击Ctrl-D来正常注销。当服务器超时时,这些都不起作用,但幸运的是,我可以Enter-~-.退出会话。
但是,这会让我回到本地会话并退出所有跳转。我该如何退出当前 ssh 会话而不退出之前的跳转?