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

通过Bash脚本运行Python脚本出现f-string语法错误求助

PyQt5脚本通过Bash连续运行报错的解决方案

问题描述

我有两个基于PyQt5开发的Python脚本,单独运行时均正常。为实现第一个脚本结束后自动运行第二个脚本,编写了如下Bash脚本:

#!/bin/bash

python /FILEPATH/FILE1.py ;
python /FILEPATH/FILE2.py

但执行该Bash脚本时,两个脚本均出现错误,错误信息指向第一个脚本第149行、第二个脚本第139行的self.label_2.setText(f'Invalid: {input_str}')语句末尾的单引号。两个脚本仅内部CARD_DICT字典的内容不同,完整代码如下:

import sys
import os

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import QMovie, QPixmap
from PyQt5.QtWidgets import *

WINDOW_STYLE = '''
background-color:black; 
color:white;
'''


class Ui_Widget(QWidget):
    
    # You need to change this
    CARD_DICT = {
        # PIN:  IMAGE_PATH
        '1360739516458': 'images/1.png',    # Right lung
        '1360743335192': 'images/2.png',    # Left lung apex
        '1360341692930': 'images/3.png',    # Left heart
        '136073147157207': 'images/4.png',  # Spleen
        '136075353245': 'images/5.png',     # Subxiphoid cardiac
        # '136072179130241': 'images/6.png',  # Diaphragm?
        # '136073133188248': 'images/7.png',  # Supra umbilicus
        # '136035223197177': 'images/8.png',  # right lateral
        # '1360341562547': 'images/9.png',    # left lateral
        # '13607311245156': 'images/10.png',   # Sub umbilicus
        # the following are for testing purposes only
        '60013620412116': 'images/6.png',  # Diaphragm?
        '13603447120253': 'images/7.png',  # Supra umbilicus
        '1360341002204': 'images/8.png',  # right lateral
        '13607217912415': 'images/9.png',    # left lateral
        '136073209222206': 'images/10.png',   # Sub umbilicus
    }

        
    def __init__(self):
        super(Ui_Widget, self).__init__()
        self.setWindowTitle('Simulated Ultrasound')
        # Full screen
        self.setWindowState(Qt.WindowMaximized)
        # No close, minimize and miximaze window button
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
        self.setStyleSheet(WINDOW_STYLE)
        self.setupUi(self)

    def setupUi(self, Widget):
        Widget.setObjectName("Widget")
        Widget.resize(800, 600)

        self.verticalLayout_2 = QtWidgets.QVBoxLayout(Widget)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        self.gridLayout.setObjectName("gridLayout")

        self.label = QtWidgets.QLabel(Widget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
        self.label.setSizePolicy(sizePolicy)

        font = QtGui.QFont()
        font.setPointSize(50)
        
        self.label.setFont(font)
        self.label.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)

        self.verticalLayout_2.addLayout(self.gridLayout)

        self.lineEdit = QtWidgets.QLineEdit(Widget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.lineEdit.sizePolicy().hasHeightForWidth())
        self.lineEdit.setSizePolicy(sizePolicy)
        self.lineEdit.setMinimumSize(QtCore.QSize(780, 0))
        self.lineEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.lineEdit.setObjectName("lineEdit")
        self.verticalLayout_2.addWidget(self.lineEdit)

        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
        self.horizontalLayout.setSpacing(10)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.label_2 = QtWidgets.QLabel(Widget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
        self.label_2.setSizePolicy(sizePolicy)
        self.label_2.setMinimumSize(QtCore.QSize(0, 10))
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)

        spacerItem = QtWidgets.QSpacerItem(
            40, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum
        )
        self.horizontalLayout.addItem(spacerItem)

        self.pushButton = QtWidgets.QPushButton(Widget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
        self.pushButton.setSizePolicy(sizePolicy)
        self.pushButton.setMinimumSize(QtCore.QSize(0, 26))
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)

        self.verticalLayout_2.addLayout(self.horizontalLayout)

        self.retranslateUi(Widget)
        QtCore.QMetaObject.connectSlotsByName(Widget)
        # I think this is the line to change to make it launch another script
        self.pushButton.pressed.connect(Widget.close) # type: ignore
        # self.pushButton.pressed.connect(Widget.post_intervention) # type: ignore
        # Check every time the text line input changed
        self.lineEdit.textChanged.connect(self.submit_pass) # type: ignore

    def retranslateUi(self, Widget):
        _translate = QtCore.QCoreApplication.translate

        Widget.setWindowTitle(_translate("Widget", "Widget"))
        self.label.setText(_translate("Widget", "Scan patient to begin"))
        self.lineEdit.setPlaceholderText(_translate("Widget", "PIN Phrase"))
        self.label_2.setText(_translate("Widget", "Arthur: PRE-intervention"))
        self.pushButton.setText(_translate("Widget", "Click here after performing interventions"))

    def submit_pass_str(self, input_str):
        """here the application accept user input"""
        if input_str in self.CARD_DICT:
            self.display_image(self.CARD_DICT[input_str])
            self.label_2.setText('')
        else:
            self.label_2.setText(f'Invalid: {input_str}')

    def display_image(self, path):
        name, ext = os.path.splitext(path)
        if ext and ext.lower() == '.gif':
            movie = QMovie(path)
            self.label.setMovie(movie)
            movie.start()
        else:
            image = QPixmap(path)
            self.label.setPixmap(image)
        self.label.setMinimumSize(1, 1)

    def submit_pass(self):
        """Usage example using PIN Phrase input form"""
        self.submit_pass_str(self.lineEdit.text())

app = QApplication(sys.argv)
window = Ui_Widget()
window.show()
# sys.exit(post_intervention())
sys.exit(app.exec_())

原因分析

  • 核心错误是Bash脚本中调用的python命令默认指向Python 2.x版本,而代码中使用的f-string(f'Invalid: {input_str}')是Python 3.6及以上版本才支持的语法,Python 2.x无法解析该语法,因此报出单引号相关的语法错误。
  • 单独运行脚本时,你实际使用的是Python 3环境(比如python3命令),所以语法没问题;但Bash环境中python命令的默认指向与单独运行时不一致,导致报错。

解决方案

1. 修改Bash脚本,明确指定Python3解释器

将Bash脚本中的python替换为python3(如果系统中Python3的命令是python3),或直接使用Python3的绝对路径:

#!/bin/bash

python3 /FILEPATH/FILE1.py
python3 /FILEPATH/FILE2.py

注:代码中的分号可省略,换行即可实现脚本顺序执行。

2. 为Python脚本添加Shebang行

在每个Python脚本的最顶部添加以下代码,确保脚本默认使用Python3运行:

#!/usr/bin/env python3

然后给脚本添加可执行权限:

chmod +x /FILEPATH/FILE1.py /FILEPATH/FILE2.py

之后Bash脚本可直接调用脚本文件:

#!/bin/bash

/FILEPATH/FILE1.py
/FILEPATH/FILE2.py

3. 额外检查:工作目录问题

脚本中图片路径为相对路径(如images/1.png),如果Bash脚本运行时的工作目录不是脚本所在目录,会导致图片加载失败。可在Bash脚本中先切换到脚本目录:

#!/bin/bash

cd /FILEPATH/
python3 FILE1.py
python3 FILE2.py

内容的提问来源于stack exchange,提问作者user3568395

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:36:41