在 Windows 版 Openssh 下,是否有办法为 powershell 指定带有嵌入引号的 exec 字符串?由于必须用引号括住多字命令,因此情况变得复杂,而且我找不到转义嵌入引号的方法。我尝试使用以下参数来 Match ... Exec:
# This gives error ${CMDVAR} is not recognized
"powershell -command ${CMDVAR}"
# This executes the script but hangs at script exit
"powershell myscript.ps1"
# This simply hangs
"powershell -command 'my long script with ^"embedded^" quotes"
这里的目标是执行这个嵌套的 powershell 单行:
if ((wmic process where "ProcessID = $((Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId)" get commandline /value| measure-object -Word).Words -gt 2) { exit 1 }
答案1
我思考如果没有外部脚本文件这是不可能的。
首先要意识到的是,在 OpenSSH 中,为 指定的命令Match Exec
需要用双引号括起来(在配置文件中),因为为 的参数Exec
使用以下方式匹配strdelim
:
/* All other criteria require an argument */
if ((arg = strdelim(&cp)) == NULL ||
*arg == '\0' || *arg == '#') {
error("Missing Match criteria for %s", attrib);
result = -1;
goto out;
}
并且strdelim
仅接受双引号作为分隔符:
#define QUOTE "\""
/* return next token in configuration line */
static char *
strdelim_internal(char **s, int split_equals)
{
char *old;
int wspace = 0;
if (*s == NULL)
return NULL;
old = *s;
*s = strpbrk(*s,
split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE);
if (*s == NULL)
return (old);
if (*s[0] == '\"') {
memmove(*s, *s + 1, strlen(*s)); /* move nul too */
/* Find matching quote */
if ((*s = strpbrk(*s, QUOTE)) == NULL) {
return (NULL); /* no matching quote */
} else {
*s[0] = '\0';
*s += strspn(*s + 1, WHITESPACE) + 1;
return (old);
}
}
// ...
所以,只能使用双引号来分隔命令。
然后,要意识到的第二件事是,在 Windows 的 OpenSSH 中,指令中使用的命令Exec
是使用以下命令执行的system
:
/*
* Execute a command in a shell.
* Return its exit status or -1 on abnormal exit.
*/
static int
execute_in_shell(const char *cmd)
{
char *shell;
pid_t pid;
int status;
#ifdef WINDOWS
return system(cmd);
#else
因此它被执行在cmd.exe
(见https://learn.microsoft.com/en-us/cpp/c-language/system-function?view=msvc-170)。 在cmd.exe
,您需要使用双引号来括住参数,单引号没有特殊含义。
问题是 OpenSSH 中没有办法转义内部双引号。
回到你的例子:
# This gives error ${CMDVAR} is not recognized
"powershell -command ${CMDVAR}"
此处不清楚 中是什么CMDVAR
,并且如上所述,您需要在 周围使用转义双引号${CMDVAR}
,而这目前在 OpenSSH 中是不可能的。
# This executes the script but hangs at script exit
"powershell myscript.ps1"
也许这可以有用"powershell -File myscript.ps1"
?
# This simply hangs
"powershell -command 'my long script with ^"embedded^" quotes"
正如所提到的,cmd.exe 需要双引号,因此参数-command
需要用转义的双引号括起来,而这目前在 OpenSSH 中是无法实现的。