简体   繁体   中英

NameError When Running Python script through Bash

I am trying to run some python (Django) files via Bash (for some cronjobs); however I am coming across some odd errors. Setup is basically a.sh script I run with bash that loads some source files & then runs a python file via Django Shell.For demonstration purposes I have commented out some parts of the bash script, that I was using during testing.

Bash Script


    #!/bin/bash
    
    source /home/grlaer/Desktop/mensam_games/bin/activate
    source /home/grlaer/Desktop/mensam_games/vars.env
    
    cd /home/grlaer/Desktop/mensam_games/cards_refactor
    
    #python3 manage.py shell < tcg_sku/test_bash.py
    ./manage.py shell < tcg_sku/test_bash.py
    
    #cat tcg_sku/test_bash.py | ./manage.py shell
    
    exit 0

Python Script

    from datetime import datetime
    
    print(datetime.now())
    
    def do_this():
        print("Its printing datetime")
        print(datetime.now())
        return None
    
    do_this()

Error/Traceback

    2022-01-16 00:11:02.698550
    Its printing datetime
    Traceback (most recent call last):
      File "./manage.py", line 22, in <module>
        main()
      File "./manage.py", line 18, in main
        execute_from_command_line(sys.argv)
      File "/home/grlaer/Desktop/mensam_games/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
        utility.execute()
      File "/home/grlaer/Desktop/mensam_games/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "/home/grlaer/Desktop/mensam_games/lib/python3.8/site-packages/django/core/management/base.py", line 330, in run_from_argv
        self.execute(*args, **cmd_options)
      File "/home/grlaer/Desktop/mensam_games/lib/python3.8/site-packages/django/core/management/base.py", line 371, in execute
        output = self.handle(*args, **options)
      File "/home/grlaer/Desktop/mensam_games/lib/python3.8/site-packages/django/core/management/commands/shell.py", line 93, in handle
        exec(sys.stdin.read())
    
    File "<string>", line 12, in <module>
    File "<string>", line 9, in do_this
    NameError: name 'datetime' is not defined

I run bash test_bash.sh from the command line, and I get the error above; However if I make datetime a global variable OR if I make datetime a function parameter it works as intended. Likewise if I tweak the bash script so that instead of trying to run the python file from the django shell it runs with just python it works as intended.

Likewise I can fix it by adding the following below my imports, but that doesn't seem proper.


    globals().update(locals())

This Works

    from datetime import datetime

    globals().update(locals())

    print(datetime.now())
    
    def do_this():
        print("Its printing datetime")
        print(datetime.now())
        return None
    
    do_this()

This Works

    from datetime import datetime

    print(datetime.now())
    
    def do_this(datetime):
        print("Its printing datetime")
        print(datetime.now())
        return None
    
    do_this(datetime)

It appears the issue has something to do with managing local vs. global variables when running a Python script via Django Shell via a Bash script. My understanding is that when I import datetime, it is going into the locals() dictionary, but it is never copied over to the globals() dict. So when the function do_this() is ran it looks in the locals() dict of the function do_this() for datetime, but its not there so it looks for it in the globals() dict and its not there as well. The problem comes from when the script is called without passing the globals and locals parameters, then by default, the globals() and locals() dictionary of the current scope will be used. So I can fix it by running globals().update(locals()) after my imports, but it does not seem like the proper solution to this problem.

thanks,I also met this issue that ember python django shell into bash script shell,the key point is indeed globals().update(locals())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM