EMACS-DOCUMENT

=============>集思广益

在Org-mode中执行code-block时如何输入密码

1 提问:在Emacs org-mode中执行code-block时如何输入密码呢?

我在Org文件中有一个shell的代码块. 在这个代码块中包含了"sudo"命令. 当我执行这段代码块时本应该要提示我输入密码的,但是结果却告诉我"sudo"命令执行失败. 请问有什么方法能够以交互式的方式执行代码块吗?

2 答案

2.1 itsjeyd的答案

是的,只要为 #+BEGIN_SRC 行加上适当的header arguments 就行了:

#+BEGIN_SRC sh :dir /sudo::                                                                       
  apt-get update                                                                                    
#+END_SRC                                                                                         

来源是:emacs-orgmode邮件列表中的 Running a sudo in a #+begin_src sh fails to get tty and askpass.

解释一下: :dir 参数的意义

指定代码块执行时的默认目录. 若省略该参数,则使用当前buffer的相关目录.

当将 /sudo:: 传递給 :dir 参数时,我们实际上是用了TRAMP 的语法来使用管理员权限来访问文件或目录. 注意到在上面这个例子中我们在 :: 后并没有指定一个目录. 这时默认使用的是 /root. 因此本质上我们在是告诉Org Babel:"以root身份访问/root并将该路径作为执行该代码的默认目录".

当然你也可以指定一个其他目录,只要将 /sudo:: 改为 /sudo::/path/to/dir 即可

若你需要在代码块中以非管理员的权限运行命令,则可以在要执行的命令前加上 sudo -u <username> (其中<username>为普通用户名称). 例如,假设你的用户名为 enchanter,你希望代码块中那些无需管理员权限的命令以你自己用户的身份来运行,则你需要在每个这种命令前加上前缀 sudo -u enchanter.

你可以用 whoami 来实验一下: 将

#+BEGIN_SRC sh :dir /sudo::                                                                       
  whoami                                                                                            
  sudo -u enchanter whoami                                                                          
  whoami                                                                                            
#+END_SRC                                                                                         

添加到你的org-mode文件中,然后执行一下.输出结果应该是:

#+RESULTS:                                                                                        
| root       |                                                                                    
| enchanter  |                                                                                    
| root       |                                                                                    

相关链接

2.2 Enzo Chi的答案

itsjeyd的回答很适合大多数命令都要以 sudo 来运行的情况.

但是若你只有小部分命令需要以 sudo 来运行时,你的代码中就会到处充满了 sudo -u <username>,并且若你希望代码能给别人运行时,你还需要将用户名作为变量来传递进去.

在这种情况下,我觉得可以使用 echo <password> | sudo -S <your command> 来解决这个问题.

举个例子:

#+BEGIN_SRC sh :var PASSWORD=(read-passwd "Sudo Password: ")                                      
  # some normal commands here and there

  # run sudo
  echo ${PASSWORD} | sudo -S <your command>

  # more normal commands
#+END_SRC