首页 > 解决方案 > 如何在 shell 中 su 和运行 python 脚本?

问题描述

我想要做的是让我的 shell 脚本在由 shell 运行的 python 脚本异常退出时停止。但是我必须 su 到 ossadm 才能运行 python 脚本,当我 su 时如何获得正确的退出代码

这是我的代码:

# shell script
    su ossadm <<EOF
    . /opt/oss/manager/bin/engr_profile.sh # which only can be executed by ossadm
    python ${SRC_DIR}/main.pyc
    echo $?
    if [[ $? = 0 ]]; then
        echo "success"
    else
        echo "failure: $?"
    fi
EOF

# main.py
def main():
    sys.exit(1) # for testing

然后运行脚本,它总是打印"0""suceess",或者更改顺序:

    su ossadm <<EOF
    . /opt/oss/manager/bin/engr_profile.sh # which only can be executed by ossadm
    python ${SRC_DIR}/main.pyc
EOF
    echo $?
    if [[ $? = 0 ]]; then
        echo "success"
    else
        echo "failure: $?"
    fi

# main.py
def main():
    sys.exit(1) # for testing

这个会给我更奇怪的“1”和“成功”。

这种处理可以在shell脚本中完成吗?

标签: pythonshellexit

解决方案


您需要引用EOF令牌。否则,here-doc 中的变量将由原始 shell 扩展,因此$?包含您之前运行的最后一个命令的退出状态su

# shell script
su ossadm <<'EOF'
    . /opt/oss/manager/bin/engr_profile.sh # which only can be executed by ossadm
    python "${SRC_DIR}"/main.pyc
    status=$?
    echo $status
    if [[ $status = 0 ]]; then
        echo "success"
    else
        echo "failure: $?"
    fi
EOF

如果SRC_DIR是在原始 shell 中设置的变量,请确保将其导出,以便由运行的 shell 继承它su,因为原始 shell 将不再扩展它。但如果它是由 设置的engr_profile.sh,引用令牌将使其正确扩展。

您获得第二1success版本的原因是该echo声明$?基于其自身的成功设置。如果要打印退出状态并对其进行测试,则需要将其保存在另一个变量中,就像我对status上面的变量所做的那样。


推荐阅读