Zsh 为用户输入命令

Zsh 为用户输入命令,zsh,Zsh,我已经编写了一个ZSH函数,它的输出是一个命令行,运行一个我需要用户能够与之交互的程序 目前,我只是回显命令行,并指示用户复制粘贴它,以便他们有必要访问其管道,但是,有没有一种方法可以通过为用户输入命令来完成该功能,就像他们自己复制和粘贴它一样 我曾研究过使用zle,但这似乎需要密钥绑定,而我只希望用户能够运行:myzshfunction arg1,最终结果是他们的终端连接到程序,该程序是通过对arg1进行某些处理而启动的 该函数如下所示: myzshfunction() { if [[ $

我已经编写了一个ZSH函数,它的输出是一个命令行,运行一个我需要用户能够与之交互的程序

目前,我只是回显命令行,并指示用户复制粘贴它,以便他们有必要访问其管道,但是,有没有一种方法可以通过为用户输入命令来完成该功能,就像他们自己复制和粘贴它一样

我曾研究过使用zle,但这似乎需要密钥绑定,而我只希望用户能够运行:myzshfunction arg1,最终结果是他们的终端连接到程序,该程序是通过对arg1进行某些处理而启动的

该函数如下所示:

myzshfunction() {
  if [[ $# = 0 ]]
  then
    echo "usage: myzshfunction 1.2.3.4"
    return
  fi

  local creds=`curl "https://xxx/$1/latest" | jq -r 'x'`
  local cred_arr=("${(@s|/|)creds}")
  local pwd_pipe=$(mktemp -u)
  mkfifo $pwd_pipe
  exec 3<>$pwd_pipe
  rm $pwd_pipe
  echo $cred_arr[2] >&3
  echo "Run this: sshpass -d3 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "$cred_arr[1]@$1"
  exec 3>&-
}
TIA使用print-z将文本添加到缓冲区。从文件中:

-z     Push the arguments onto the editing buffer stack, separated by spaces.
调用下面定义的foo将导致hi被放置在命令行上,就像用户键入它一样。比如说,

% foo () { print -z hi; }
% foo
% hi

我能想到的最好的解决方案是使用zle——Zsh行编辑器

这可以让您更新用户当前正在编辑的命令,我觉得这有点不方便。我更喜欢一种解决方案,它允许您调用一个函数,点击return,然后干净地运行一个函数,并将STDIO连接到您的终端,就好像您已经运行了生成的命令行一样

也许您可以通过绑定返回键并从那里执行某种决策/路由来模拟这一点,以查看用户是否希望调用myfunc。目前,我的解决方案要求在键入$host的目标后输入Esc+i序列


你能分享你函数的代码吗?或者可能是某种公司机密?我添加了一个修订版的functionAh,很有趣。请原谅我的无礼。我看到了类似的东西。它使用xclip来实现。也许你认为它可以满足你的需要?备份一点,为什么用户需要在执行之前修改给定的命令行?@chepner用户给一些输入一个他们想要SSH的IP地址,脚本获取cred以便登录到该主机,然后我想自动将用户直接放到与该主机的SSH会话中这接近于我想要的,虽然它与传递密码的匿名管道方法不兼容,因为fd仍然属于以前运行的命令。当函数退出时,您可以让file descriptor 3保持打开状态,但是的,最好先使用zle小部件编辑和执行命令行。正在查找,请稍候…更新:从未找到该命令。我认为有一些类似于vared的东西,但用于命令。我可能会想到fc,这在这里并不完全合适,因为您首先必须使用所需的命令填充历史记录。这是可行的,但有点冗长。我已经用zle实现了这一点,但使用bindkey序列有点恶心,而不仅仅是能够输入我的原始命令,点击return,然后让魔法发生
% foo () { print -z hi; }
% foo
% hi
zle-myfunc() {
  apikey=$(keychain-environment-variable api-key)
  if [ $? -ne 0 ]; then
    echo "Add your api-key to the keychain: "
    BUFFER='security add-generic-password -U -a ${USER} -D "environment variable" -s "api-key" -w'
    zle accept-line
    return 1
  fi
  local host=$BUFFER
  zle kill-buffer
  local creds=`curl ..." | jq -r ...`
  if [ -z creds ]; then
    echo "Couldn't get creds, check your network"
    return 1
  fi
  local creds_arr=("${(@s|/|)creds}")
  local pwd_pipe=$(mktemp -u)
  mkfifo $pwd_pipe
  exec 3<>$pwd_pipe
  # anonymise the pipe
  rm $pwd_pipe
  echo "$creds_arr[2]" >&3
  BUFFER="sshpass -d3 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $creds_arr[1]@$host"
  zle accept-line
  # exec 3>&-
}
zle -N zle-myfunc
bindkey '\ei' zle-myfunc