You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker-compose脚本中如何转义bash命令里的美元符号$

解决Docker Compose中Nginx配置$符号丢失的问题

问题原因

你遇到的是多层Shell转义导致的$符号解析丢失:你的command里嵌套了两层Bash调用(bash -c 内部又用bash -s <<EOF),每一层都会解析$符号,所以原本的转义方式不足以保留最终需要的$1。

解决方案

方案1:增加转义层级(适配原有嵌套结构)

把rewrite行的/$$1改成/$$$$1,这样经过两层Shell解析后,最终写入nginx.conf的就是$1:

app-reverse-proxy:
    image: nginx:1.23
    ports:
      - "9090:80"
    command: |
      bash -c 'bash -s << EOF
        cat > /etc/nginx/nginx.conf << EON
          daemon off;
          user www-data;
          events {
            worker_connections 1024;
          }
          http {
            gzip on;
            gzip_disable "msie6";
            include /etc/nginx/mime.types;
            server {
              listen 80;
              root /var/www/html;
              index index.html;
              location ^~ /rooturl/ {
                proxy_pass http://other-app:8080;
                rewrite /rooturl(.*) /$$$$1 break; 
              }
            }
          }
      EON
      nginx
      EOF'
    depends_on:
      - other-app
    networks:
      - docker-net
  • 解析逻辑:最外层bash -c会把$$$$解析为$$,内部bash -s再把$$解析为$,最终得到$1。

方案2:简化Shell调用(更易维护)

去掉多余的bash -s <<EOF嵌套,直接在bash -c里写命令,这样只需要一次转义(\$1)就能保留$1:

app-reverse-proxy:
    image: nginx:1.23
    ports:
      - "9090:80"
    command: |
      bash -c '
        cat > /etc/nginx/nginx.conf <<EON
          daemon off;
          user www-data;
          events {
            worker_connections 1024;
          }
          http {
            gzip on;
            gzip_disable "msie6";
            include /etc/nginx/mime.types;
            server {
              listen 80;
              root /var/www/html;
              index index.html;
              location ^~ /rooturl/ {
                proxy_pass http://other-app:8080;
                rewrite /rooturl(.*) /\$1 break; 
              }
            }
          }
      EON
      nginx
      '
    depends_on:
      - other-app
    networks:
      - docker-net

方案3:无需rewrite,用proxy_pass路径直接实现前缀移除

更简洁的方式:在proxy_pass末尾加上/,Nginx会自动去掉/rooturl/前缀,把剩余路径转发到后端:

app-reverse-proxy:
    image: nginx:1.23
    ports:
      - "9090:80"
    command: |
      bash -c '
        cat > /etc/nginx/nginx.conf <<EON
          daemon off;
          user www-data;
          events {
            worker_connections 1024;
          }
          http {
            gzip on;
            gzip_disable "msie6";
            include /etc/nginx/mime.types;
            server {
              listen 80;
              root /var/www/html;
              index index.html;
              location ^~ /rooturl/ {
                proxy_pass http://other-app:8080/;
              }
            }
          }
      EON
      nginx
      '
    depends_on:
      - other-app
    networks:
      - docker-net
  • 效果:比如请求http://localhost:9090/rooturl/path/to/api会被转发到http://other-app:8080/path/to/api,完全满足你的需求,还避免了$符号转义的麻烦。

内容的提问来源于stack exchange,提问作者João Pedro Schmitt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:18:50