-c commands are read from string.

Preface

我们再不同的地方看到这个命令加在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 会给后面的 shell 命令授权, 但仅此而已. 如果后面还接有其他命令, 就会显示Permission denied, 因为后面的命令并没有被授权

sh -c "command ..." 就是对后面的一整条命令整体授权, 所以多个命令需要使用 sh -c

  • 举例
sudo echo "追加一条信息" >> test

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


(完)

单引号和双引号并不一样

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 拥有, 这可能会出现各种问题

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐