sh -c 的原因

本文介绍了在Dockerfile中常见到的sudo sh -c命令的用法,解释了其用于授权后续shell命令的原因。通过示例展示了为何在执行多条命令时需要使用sh -c,以及单引号和双引号的区别。同时,提到了sudo -H的作用,即设置HOME环境变量为目标用户的主目录,避免权限问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TLDR

手册里面的解释:

-c commands are read from string.

加上的原因:希望将后面的命令作为一个整体去执行。(命令在搭配 “条件执行 (&&, ||)” 等技巧, 可以一次执行多段命令)

分析

我们在不同的地方, 可以看到这个命令被加在 shell 命令前

  • 比如 Dockerfile
FROM openjdk:12-alpine
MAINTAINER icyfenix
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JAVA_OPTS="" \
    PROFILES="default"
ADD /target/*.jar /bookstore.jar
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /bookstore.jar --spring.profiles.active=$PROFILES"]
EXPOSE 8080
  • 另一个例子 sudo
> sudo echo "追加一条信息" >> test
> Permission denied

原因

在用 sudo 命令时, 希望 sudo 会给后面的 shell 命令授权, 但 sudo 仅能给后面紧接的命令授权. 如果后面还接有其他命令, 就会显示 Permission denied, 因为后面剩余的命令并没有进行授权

sh -c "command ..." 可以达到这个目的, 将所有的命令作为一整条命令整体授权, 所以多个命令需要使用 sh -c

Permission denied 是因为重定向符号 >> 也属于 shell 命令, 所以虽然 echo 已经授予 root 权限, 但是 >> 并没有授权, 导致最终展示 Permission denied


(THE END)

单引号和双引号并不一样

sudo -H bash -c "echo $HOME $USER"
# 并不一样
sudo -H bash -c 'echo $HOME $USER'

Why

双引号会使用 $ 的含义, 实际上变为: sudo -H bash -c echo 实际值 实际值

详细区别

  • 单引号

将字符括在单引号中会保留引号内每个字符的文字值. (单引号之间不能出现单引号,即使前面有反斜杠)

  • 双引号

将字符括在双引号 ( ") 中会保留引号内所有字符的字面值,但 $、`、\ 和 历史扩展时的 ! 除外. 字符$ 和 `在双引号内保留其特殊含义(请参阅Shell Expansions)。反斜杠仅在后跟以下字符之一时才保留其特殊含义:$, `, ",\ 或换行符。在双引号内,删除后面跟有这些字符之一的反斜杠。没有特殊含义的字符前面的反斜杠保持不变。双引号可以用反斜杠在双引号中引用。如果启用,将执行历史扩展,除非 !出现在双引号中的使用反斜杠进行转义。前面的 反斜杠+! 不会被删除.

sudo -H 为什么要加 -H

-H, --set-home
    Request that the security policy set the HOME environment
    variable to the home directory specified by the target user's
    password database entry. Depending on the policy, this may be
    the default behavior.

加了 -H 会使用 root 的主目录 ($HOME).

否则会将使用当前用户的主目录, 导致用户主目录中的某些文件被 root 拥有, 这可能会出现各种问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值