Shell脚本if语句内执行Python命令报错的解决方法
解决Docker Entrypoint脚本中if分支内Here-Document的EOF语法错误
这个报错我之前也碰到过,核心问题出在here-document的缩进处理上,咱们一步步来解决:
错误原因分析
你用了<<-EOF来定义here-document,这个语法的特性是只会忽略前导的制表符(Tab键输入的),如果你的EOF行前面用的是空格缩进,bash就识别不出这是here-document的结束标记,会一直读到脚本末尾,就会抛出你看到的"delimited by end-of-file"警告和语法错误。另外你代码里的{}大括号其实是多余的,完全可以去掉。
两种可行的解决方案
方案1:修正Here-Document的缩进规则
如果你坚持要保留python manage.py shell <<-EOF的写法,必须保证结束标记EOF前面的缩进是制表符(Tab),而不是空格。或者直接去掉<<-里的减号,让EOF顶格写:
#!/usr/bin/env bash ############### App ############### if [ "$SERVICE_TYPE" = "app" ] then echo "I'm a Application instance, Hello World!" # ...你的其他代码 echo "Checking if System User is setup" # 去掉多余的大括号,确保EOF前是制表符(如果用<<-EOF) python manage.py shell <<-EOF from django.contrib.auth import get_user_model User = get_user_model() # get the currently active user model # 注意:Django默认用户模型的用户名字段是username,不是user,这里要对应你的模型字段 User.objects.filter(username='$SYS_USER').exists() or User.objects.create_superuser('$SYS_USER', '$SYS_EMAIL', '$SYS_PASSWORD') EOF # 上面的EOF前面必须是Tab,不能是空格! # ...你的其他代码 elif [ "$SERVICE_TYPE" = "celery-worker" ] then echo "I'm a Celery Worker instance, Hello World!" # ...你的其他代码 elif [ "$SERVICE_TYPE" = "celery-beat" ] then echo "I'm a Celery Beat instance, Hello World!" # ...你的其他代码 fi
方案2:改用Cat管道方式(更稳妥)
直接用你参考的cat <<EOF | python manage.py shell写法,这种方式完全避开了here-document的缩进陷阱,在if分支里也能完美运行,我个人更推荐这种:
#!/usr/bin/env bash ############### App ############### if [ "$SERVICE_TYPE" = "app" ] then echo "I'm a Application instance, Hello World!" # ...你的其他代码 echo "Checking if System User is setup" # 和你参考的代码一致,完全避开缩进问题 cat <<EOF | python manage.py shell from django.contrib.auth import get_user_model User = get_user_model() # get the currently active user model # 修正字段名(如果用默认Django用户模型),补全create_superuser的参数 User.objects.filter(username='$SYS_USER').exists() or User.objects.create_superuser('$SYS_USER', '$SYS_EMAIL', '$SYS_PASSWORD') EOF # ...你的其他代码 elif [ "$SERVICE_TYPE" = "celery-worker" ] then echo "I'm a Celery Worker instance, Hello World!" # ...你的其他代码 elif [ "$SERVICE_TYPE" = "celery-beat" ] then echo "I'm a Celery Beat instance, Hello World!" # ...你的其他代码 fi
额外注意事项
- Django用户模型字段:默认的Django用户模型中,用户名字段是
username,不是user,如果你的自定义模型没有修改这个字段,记得把User.objects.filter(user='$SYS_USER')改成User.objects.filter(username='$SYS_USER')。 - Create_superuser参数:Django的
create_superuser方法需要至少3个必填参数(username、email、password),你原来的代码只传了两个,会触发参数错误,建议用环境变量(比如$SYS_EMAIL、$SYS_PASSWORD)补全。
内容的提问来源于stack exchange,提问作者user11684966
相关产品推荐
相关产品推荐

