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
。如果您不需要
echo
或printf
,您可以使用来进行替换bash
(也适用于) 。例如:要做,你可以写。如果该值小于允许的最大位数(八进制为 3,十六进制为 2,Unicode 分别为 4 或 8),则应使用前导零以避免误解。例如:计算为while给出预期的。zsh
$'string'
touch foo#bar
touch $'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