使用scala进程运行相关的ubuntu命令

m1m5dgzv  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(406)

我有一台安装了本机hadoop客户端的ubuntu机器,这意味着我可以运行例如:
hadoopfs-ls只要我在某个用户上,比如说usera。
现在我在这台机器上的根目录下运行了一个scala应用程序(无法更改),我需要能够切换到usera,然后运行hadoop fs-ls
我正在使用scala.process来运行我的命令,但我无法以它们相互连接的方式运行它们,因此如果运行:
进程(seq(“bash”,“-c”,“su usera&&hadoop fs-ls”))。!我将得到一个错误,因为第二个命令实际上是在根上执行的,我知道这是因为当我这样做时:
进程(seq(“bash”,“-c”,“su usera&&whoami”)。!我得到根而不是usera
任何关于如何将它们联系在一起的想法(例如linux命令中的示例就足够了,我相信我可以在scala.process中复制它)

5vf7fwbs

5vf7fwbs1#

你的问题与scala、ubuntu或hadoop本身无关。它是关于shell脚本和理解shell工作方式的。
首先,您不需要调用bash,在您的情况下,它只是另一个(不必要的)间接层。删除bash时会留下以下内容:

Process("su userA && hadoop fs -ls").!

... 这将失败。为什么?因为这个代码相当于:

Process(Seq("su", "userA", "&&", "hadoop", "fs", "-ls")).!

你可以看到你所有的命令包括 && 传递给 su 作为命令行参数。自然地 su 不知道该怎么办,所以会失败。
现在让我们暂时忘掉scala代码,转到bashshell并在那里尝试命令。让我们使用 whoami 要测试用户是否已更改为usera:

su userA && whoami

你会注意到的第一件事是 su 当以这种方式调用时,会提供交互式shell提示(除非从根目录运行密码,否则会先请求密码)。这可能不是你跑步时想要的 su 从一个程序。此外,在您注销该shell之后,您将看到用户没有更改为usera。
这就是原因。有效用户的概念是与一个过程联系在一起的。每个进程在给定的时间点上只有一个有效用户。进程的初始有效用户是从派生进程继承的。
下面是你跑步时发生的事情 su userA && whoami 从bash提示符: bash 产卵 su 作为子进程, su 从其父级继承有效用户:

bash (root)
+- su (root)
``` `su` 通过setuid更改其有效用户:

bash (root)
+- su (userA)

默认情况下 `su` 生成指定用户的默认shell,如中所示 `/etc/passwd` 作为子进程(例如。 `sh` );  `sh` 从其父级继承有效用户:

bash (root)
+- su (userA)
+- sh (userA)

现在让我们回到 `&&` 部分。它是shell语法的一部分。 `command1 && command2` 要求shell先运行command1,然后只有aftercommand1存在且没有任何错误(即退出代码为零)运行command2。理解两件事至关重要:
只有在command1成功完成后,command2才会运行;
command1和command2都是由同一个shell进程派生的,因此它们都继承其有效用户。
所以这就是我们要得到的 `su userA && whoami` 调用:

bash (root)
+- su (userA, already exited by the time whoami started)
| +- sh (userA, already exited by the time whoami started)
+- whoami (root)

所以不管你用哪种方式 `su` 过程 `whoami` 不会受到影响。
为了解决这个问题,你应该 `whoami` 产生于 `su` 以便它可以继承已更改的用户。
为了实现这一点 `su` 这样地:

su -c whoami

这将生成以下流程树:

bash (root)
+- su (userA)
+- whoami (userA)

现在让我们回到斯卡拉。不幸的是,如果从scala运行上面的命令 `su: must be run from a terminal` . 老实说,我不知道如何正确地处理这个问题,所以我建议改用 `sudo` 相反。
所以最终的解决方案是:

Process(Seq("sudo", "-u", "userA", "hadoop fs -ls")).!

相关问题