【问题标题】:Not able to execute Unix commands containing variables using JSch library无法使用 JSch 库执行包含变量的 Unix 命令
【发布时间】:2018-02-23 10:42:48
【问题描述】:

我编写了一个 Java 程序,执行时会打开一个上传向导,用户可以通过该向导选择文件。完成此操作后,所选文件将被传输/上传到 Unix 盒子到用户指定并进一步处理的目录。以下是步骤/操作:

  1. 通过上传向导浏览文件
  2. 之后程序会提示创建一个新目录,用户可以输入该目录的名称
  3. 程序创建一个新目录(源)并将选定的文件放在服务器创建的目录中
  4. 在源中显示传输文件的内容(使用 cat 命令)
  5. 提示用户创建一个新目录(目标),将文件从源复制到目标,然后在目标中显示文件的内容,所有这些都使用 Linux 命令。

我可以将文件上传到源(第 3 步)。但是,第 4 步和第 5 步不起作用。代码如下:

String cmd1 = "cat" + " " + path + s1 + "/" + file;
System.out.println(cmd1);
((ChannelExec)channel).setCommand(cmd1);
Scanner in2 = new Scanner(System.in);
System.out.println("Enter d target directory");
String s = in2.nextLine();
String path2 = "/e/f/";
String d = path2 + s;
String cmd2 = "mkdir" + " " + path2 + s;
((ChannelExec)channel).setCommand(cmd2);
String src = p + "/" + file;
String cmd3 = "cp" + " " + path + s1 + "/" + file + " " + path2 + s;
((ChannelExec)channel).setCommand(cmd3);
String destpath = d + "/" + file;
String cmd4 = "cat" + " " + path2 + s + "/" + file;

我无法使程序在命令中使用变量(用于用户输入)。但是,硬编码的字符串例如,例如。 cat /a/b/file 好像可以工作了。

有人可以在这方面帮助我吗?

【问题讨论】:

  • 请提供您忘记的代码?
  • 程序中的字符串 s1 被视为用户输入。(我可以上传文件的来源)。
  • 只选择一个您有问题的命令。我们需要minimal reproducible example
  • 你调试过你的代码吗?执行之前cmd1 的确切值是多少?
  • 嗨马丁,字符串 cmd1 = "cat" + " " + path + s1 + "/" + file;首先。但是,cp 和 mkdir 似乎都不起作用。

标签: java jsch


【解决方案1】:

从你的 sn-p 我猜channel 是一个ChannelExec,这是一个只用于发布命令的通道,像 shell 一样工作(该用例由shell 通道,它分配一个伪 tty)。

在您的情况下,我会简化代码,根本不使用变量。否则,如果您绝对需要它们,您可以:

  • 如果变量被定义你的Java程序调用ChannelExec.setEnv(name, value)
  • 如果变量是在目标主机上定义的,请确保它位于正确的位置,例如在生成非交互式 SSH 会话时来源的文件。一个好地方可能是.bashrc,但你应该检查你的系统文档(也许this other answer

【讨论】:

  • 在这种情况下,这里的 的值是多少?我不确定我是否遵循这个概念。 :(
  • 也许我误解了你的问题。当您说程序仅适用于硬编码路径而不适用于变量时,您的意思是您的路径采用/home/user/$TARGET/file.txt"/home/user/" + target + "/file.txt" 的形式?
  • 是的,以这种方式是“/home/user/”+目标+“/file.txt”。字符串目标的值取自​​用户。很高兴你问。 :)
  • 好的,所以这个答案不相关。如果路径在硬编码时有效,而在从用户输入组装时无效,则要么两个字符串最终彼此不同,要么甚至完全执行另一个代码路径。不幸的是,没有人知道你的 IDE 中没有断点,但幸运的是你可以 :-) 只需在有问题的行设置一个断点,然后分析你可以在两种场景之间找到的每一个差异(硬编码和来自用户输入)。我的意思是,还要查看其他变量和服务器状态
  • 是的。我也这样做了。但这两种情况似乎没有区别。我已经将命令打印到控制台,它提供了完全相同的命令,可以直接在服务器上执行。我开始怀疑 ((ChannelExec)channel).setCommand(cmd3) 不支持/使用变量。
【解决方案2】:

我认为问题在于变量值(变量d 已创建但几乎未使用)和最终/ 字符有些混乱。而且我不知道p 的值。

在执行它们之前,我会开始为cmd2cmd3 添加一个println,因为我认为在某些地方会缺少/,或者应该在哪里缺少两个/只是一个取决于用户键入的内容,并对目录进行一些规范化,因此他们总是有一个最终的/,或者他们从来没有,但我想确保无论用户输入或参数有什么,所有目录名称一致。

目录名称、用户输入和最终的/ 总是很麻烦...

【讨论】:

  • 当我在控制台上打印命令时,它们似乎没问题。例如,打印 cmd1 会给出 cat /a/b/src/file.txt。 cmd2 提供 mkdir /e/f/tgt,否则它将在终端上工作。字符串 src 和 tgt 是不带 / 字符的目录名称的用户输入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多