# 在容器中执行新命令<a name="ZH-CN_TOPIC_0184808061"></a>

## 描述<a name="zh-cn_topic_0183292669_section13350115135310"></a>

lcrc exec命令用于正在运行的容器中运行一个新命令。新执行的命令将在容器的默认目录中运行。如果基础镜像指定了自定义目录，则将使用该目录。

## 用法<a name="zh-cn_topic_0183292669_section188811239165314"></a>

```
lcrc exec [OPTIONS] CONTAINER COMMAND [ARG...]
```

## 参数<a name="zh-cn_topic_0183292669_section4322824135919"></a>

exec命令支持参数参考下表。

**表 1**  exec命令参数列表

<a name="zh-cn_topic_0183292669_table123271972373"></a>
<table><tbody><tr id="zh-cn_topic_0183292669_row11911910193715"><td class="cellrowborder" valign="top" width="17.333333333333336%"><p id="zh-cn_topic_0183292669_p1599121519378"><a name="zh-cn_topic_0183292669_p1599121519378"></a><a name="zh-cn_topic_0183292669_p1599121519378"></a><strong id="zh-cn_topic_0183292669_b129918157370"><a name="zh-cn_topic_0183292669_b129918157370"></a><a name="zh-cn_topic_0183292669_b129918157370"></a>命令</strong></p>
</td>
<td class="cellrowborder" valign="top" width="39.57575757575758%"><p id="zh-cn_topic_0183292669_p129921517375"><a name="zh-cn_topic_0183292669_p129921517375"></a><a name="zh-cn_topic_0183292669_p129921517375"></a><strong id="zh-cn_topic_0183292669_b109921517373"><a name="zh-cn_topic_0183292669_b109921517373"></a><a name="zh-cn_topic_0183292669_b109921517373"></a>参数</strong></p>
</td>
<td class="cellrowborder" valign="top" width="43.09090909090909%"><p id="zh-cn_topic_0183292669_p159941513375"><a name="zh-cn_topic_0183292669_p159941513375"></a><a name="zh-cn_topic_0183292669_p159941513375"></a><strong id="zh-cn_topic_0183292669_b699131593718"><a name="zh-cn_topic_0183292669_b699131593718"></a><a name="zh-cn_topic_0183292669_b699131593718"></a>说明</strong></p>
</td>
</tr>
<tr id="zh-cn_topic_0183292669_row27694315596"><td class="cellrowborder" rowspan="6" valign="top" width="17.333333333333336%"><p id="zh-cn_topic_0183292669_p059393215315"><a name="zh-cn_topic_0183292669_p059393215315"></a><a name="zh-cn_topic_0183292669_p059393215315"></a><strong id="zh-cn_topic_0183292669_b1060012451269"><a name="zh-cn_topic_0183292669_b1060012451269"></a><a name="zh-cn_topic_0183292669_b1060012451269"></a>exec</strong></p>
<p id="zh-cn_topic_0183292669_p17332618610"><a name="zh-cn_topic_0183292669_p17332618610"></a><a name="zh-cn_topic_0183292669_p17332618610"></a></p>
</td>
<td class="cellrowborder" valign="top" width="39.57575757575758%"><p id="zh-cn_topic_0183292669_p176843115914"><a name="zh-cn_topic_0183292669_p176843115914"></a><a name="zh-cn_topic_0183292669_p176843115914"></a>-d, --detach</p>
</td>
<td class="cellrowborder" valign="top" width="43.09090909090909%"><p id="zh-cn_topic_0183292669_p166861121233"><a name="zh-cn_topic_0183292669_p166861121233"></a><a name="zh-cn_topic_0183292669_p166861121233"></a>后台运行命令</p>
</td>
</tr>
<tr id="zh-cn_topic_0183292669_row144815810419"><td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p248105814415"><a name="zh-cn_topic_0183292669_p248105814415"></a><a name="zh-cn_topic_0183292669_p248105814415"></a>-e, --env</p>
</td>
<td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p1240225963710"><a name="zh-cn_topic_0183292669_p1240225963710"></a><a name="zh-cn_topic_0183292669_p1240225963710"></a>设置环境变量（备注：目前LCRD尚不使用此功能）</p>
</td>
</tr>
<tr id="zh-cn_topic_0183292669_row225582276"><td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p16101657289"><a name="zh-cn_topic_0183292669_p16101657289"></a><a name="zh-cn_topic_0183292669_p16101657289"></a>-H, --host</p>
</td>
<td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p10104456281"><a name="zh-cn_topic_0183292669_p10104456281"></a><a name="zh-cn_topic_0183292669_p10104456281"></a>指定要连接的LCRD socket文件路径</p>
</td>
</tr>
<tr id="zh-cn_topic_0183292669_row185407613516"><td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p115401661558"><a name="zh-cn_topic_0183292669_p115401661558"></a><a name="zh-cn_topic_0183292669_p115401661558"></a>-i, --interactive</p>
</td>
<td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p4818143019389"><a name="zh-cn_topic_0183292669_p4818143019389"></a><a name="zh-cn_topic_0183292669_p4818143019389"></a>没有连接，也要保持标准输入打开（备注：目前LCRD尚不使用此功能）</p>
</td>
</tr>
<tr id="zh-cn_topic_0183292669_row2054016654"><td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p65401663515"><a name="zh-cn_topic_0183292669_p65401663515"></a><a name="zh-cn_topic_0183292669_p65401663515"></a>-t, --tty</p>
</td>
<td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p1783413176392"><a name="zh-cn_topic_0183292669_p1783413176392"></a><a name="zh-cn_topic_0183292669_p1783413176392"></a>分配伪终端（备注：目前LCRD尚不使用此功能）</p>
</td>
</tr>
<tr id="zh-cn_topic_0183292669_row3321661767"><td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p18331961361"><a name="zh-cn_topic_0183292669_p18331961361"></a><a name="zh-cn_topic_0183292669_p18331961361"></a>-u, --user</p>
</td>
<td class="cellrowborder" valign="top"><p id="zh-cn_topic_0183292669_p93326361"><a name="zh-cn_topic_0183292669_p93326361"></a><a name="zh-cn_topic_0183292669_p93326361"></a>指定用户登录容器执行命令</p>
</td>
</tr>
</tbody>
</table>

## 约束限制<a name="zh-cn_topic_0183292669_section18811125219118"></a>

-   lcrc exec 不指定任何参数时，会默认使用-it参数， 表示分配一个伪终端，以交互式的方式进入容器
-   当使用lcrc exec 执行脚本，在脚本中执行后台进程时，需使用nohup标志忽略SIGHUP信号。

    使用lcrc exec运行脚本,在脚本中运行后台进程需使用nohup标志。否则内核会在exec执行的进程（session首进程）退出时，向后台执行的进程发送SIGHUP信号，导致后台进程退出，出现僵尸进程。

-   lcrc exec 进入容器进程后，不能执行后台程序，否则会出现卡死现象。

    lcrc exec执行后台进程的方式如下：

    1.  使用lcrc exec进入容器终端，lcrc exec container\_name bash
    2.  进入容器后，执行 script &
    3.  执行exit，导致终端卡死

    ```
    lcrc exec 进入容器后，执行后台程序卡住的原因为lcrc exec进入容器运行后台while1程序，当bash退出时，while1程序并不会退出，变为孤儿进程由1号
    进程接管，while1程序是由容器的初始bash进程fork &exec执行的，while1进程复制了bash进程的文件句柄，导致bash退出时，句柄并未完全关闭，导致
    console进程收不到句柄关闭事件，epoll_wait卡住，进程不退出。
    ```

-   lcrc exec 不能用后台方式执行，否则可能会出现卡死现象。

    lcrc exec后台执行的方式如下：

    使用**lcrc exec 脚本 & **的方式后台执行exec，如：lcrc exec container\_name script & ，lcrc exec 后台执行，执行的脚本中不断cat某一文件，正常时在当前终端有输出，如果在当前终端执行回车操作，客户端会因读IO失败而退出读stdout的动作，使终端不再输出，服务端由于进程仍然在cat文件，会继续往fifo的buffer里写入数据，当缓存写满时，容器内进程会卡死在write动作上。

-   轻量级容器使用exec执行带有管道操作的命令时，建议使用/bin/bash -c 方式执行该命令。

    典型应用场景：

    使用lcrc exec container\_name -it ls /test | grep "xx" | wc -l,用于统计test目录下xx的文件个数，因exec执行的为"ls /test",其输出通过管道进行grep、wc 处理。exec执行的为"ls /test"的输出会换行，再针对该输出进行处理时，结果有误。

    原因：使用exec 执行ls /test,输出带有换行，针对该输出进行“| grep "xx" | wc -l“，处理结果为2（两行）

    ```
    [root@localhost ~]# lcrc exec  -it container ls /test
    xx    xx10  xx12  xx14  xx3   xx5   xx7   xx9
    xx1   xx11  xx13  xx2   xx4   xx6   xx8
    [root@localhost ~]#
    ```

    建议处理方式：使用run/exec执行带有管道操作的命令时，使用/bin/bash -c 执行命令，在容器中执行管道操作。

    ```
    [root@localhost ~]# lcrc exec  -it container  /bin/sh -c "ls /test | grep "xx" | wc -l"
    15
    [root@localhost ~]#
    ```

-   禁止使用echo的方式向exec命令的stdin输入数据，会导致客户端卡死。应该直接将echo的值作为命令行参数传给容器

    ```
    [root@localhost ~]# echo ls | lcrc exec 38 /bin/sh
    
    
    ^C
    [root@localhost ~]# 
    ```

    上述命令可能出现客户端卡死现象，这是由于上述命令相当于往stdin输入ls，随后EOF被读取，客户端不再发送数据，等待服务端退出，但是服务端无法区分客户端是否需要继续发送数据，因而服务端卡在read数据上，最终导致双方均卡死。

    正确的执行方式为：

    ```
    [root@localhost ~]# lcrc exec 38 ls
    bin   dev   etc   home  proc  root  sys   tmp   usr   var
    ```


## 示例<a name="zh-cn_topic_0183292669_section1734193235916"></a>

在运行中的容器中，执行echo命令

```
$ lcrc exec c75284634bee echo "hello,world"
hello,world
```

