将 ssh 远程命令记录到“bash_history”

将 ssh 远程命令记录到“bash_history”

SSH 允许远程用户发出某些命令,而无需交互式登录到服务器,如ssh用法的最后一行所示:

usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
           [-D [bind_address:]port] [-E log_file] [-e escape_char]
           [-F configfile] [-I pkcs11] [-i identity_file]
           [-L [bind_address:]port:host:hostport] [-Q protocol_feature]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-R [bind_address:]port:host:hostport] [-S ctl_path]
           [-W host:port] [-w local_tun[:remote_tun]]
           [user@]hostname [command]

当使用远程命令调用 ssh 时,文件.bash_history不会更新(即远程命令不会添加到.bash_history)。我通过添加以下命令来“模拟”这种效果/etc/ssh/sshd_config

ForceCommand if [[ -z $SSH_ORIGINAL_COMMAND ]]; then bash; else printf "$SSH_ORIGINAL_COMMAND\n" >> .bash_history; bash -c "$SSH_ORIGINAL_COMMAND"; fi

上面的命令检查环境变量是否$SSH_ORIGINAL_COMMAND为空:

  • 如果是这样,则不会发出远程命令,我们只需运行bash.
  • 否则,$SSH_ORIGINAL_COMMAND被添加到,并执行.bash_history其中的远程命令 。$SSH_ORIGINAL_COMMAND

.bash_history它按预期工作,但我需要更多:我希望也添加当前时间戳 。为此,我添加了以下命令/etc/ssh/sshd_config

ForceCommand if [[ -z $SSH_ORIGINAL_COMMAND ]]; then bash; else printf "#`date +%s`\n$SSH_ORIGINAL_COMMAND\n" >> .bash_history; bash -c "$SSH_ORIGINAL_COMMAND"; fi

但是当我尝试ssh连接到服务器时,我收到以下错误:

bash: -c: line 0: unexpected EOF while looking for matching `"'
bash: -c: line 1: syntax error: unexpected end of file
Connection to 127.0.0.1 closed.

如果我#之前删除date +%s,它就能正常工作。但我需要#在时间戳之前打印,因为它是.bash_history文件的正确格式。

答案1

in被解释为注释的开头,其后面的所有内容都将被忽略#sshd_config虽然 (根据sshd_config(5))""可用于引用包含空格的参数,但它们不引用#

这也解释了您收到的错误。sshd只将以下内容传递给bash

if [[ -z $SSH_ORIGINAL_COMMAND ]]; then bash; else printf "

无法找到第二个",因为命令行在第一个命令行之后结束。

#为了防止这种行为,不得使用文字:

  • 无论如何,正如printf在这里使用的一样,使用其使用反斜杠转义字符的功能非常方便。#可以写成\x23(十六进制)、\43(八进制)、\u23(Unicode,十六进制最多 4 个十六进制数字) 甚至\U23(Unicode,十六进制最多 8 个十六进制数字)。 也适用于echo -e。请注意,\必须用引号引起来,因此请使用"\43"'\43'\\43

  • 如果您不需要echoprintf,您可以使用来进行替换bash(也适用于) 。例如:要做,你可以写。如果该值小于允许的最大位数(八进制为 3,十六进制为 2,Unicode 分别为 4 或 8),则应使用前导零以避免误解。例如:计算为while给出预期的。zsh$'string'touch foo#bartouch $'foo\x23bar'$'foo\u23bar'foo⎺r$'foo\u0023bar'foo#bar

  • #通过将所有功能放入脚本中,然后放入ForceCommand /path/to/script您的配置中,避免一起使用(字面或其他方式)。

第二个选项还允许您printf通过更广泛地使用格式选项来放弃date。代替

printf "\x23`date +%s`\n$SSH_ORIGINAL_COMMAND\n" >> .bash_history

你可以写

date $'+\x23%s'"${SSH_ORIGINAL_COMMAND//%/%%}" >> .bash_history

相关内容