1

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.

6
  • Does this answer your question? import statement is not working when running python script from the command line Commented Jan 16, 2022 at 2:58
  • No unfortunately my issue is solely dealing with a package that is a part of python's standard library so there is no import pathing issue to deal with. My guess at the moment is that this is an issue with how scripts ran like this have issues with maintaining their local & global variables, but not sure how to solve it properly. Commented Jan 16, 2022 at 4:22
  • The issue is you are importing the datetime module from the datetime standard library package. Then you try to use another method named datetime in your code which doesn't exist. Try just import datetime in your import then datetime.now() in your code. Commented Jan 16, 2022 at 4:58
  • I appreciate the reply, but the only datetime in the namespace is what I imported from datetime (an object type from datetime). If i just did import datetime I would have to do datetime.datetime.now() to get current datetime. Also check my traceback, I can call datetime.now() just fine outside the function at the start of my code, but it fails when ran within the function. Commented Jan 16, 2022 at 6:13
  • Do you have Ipython or bpython installed by any case? I can't seem to reproduce this. Commented Jan 16, 2022 at 15:46

1 Answer 1

0

I also had this issue that ember python django shell into bash script shell.

The solution is indeed, as mentioned in the question, to do

globals().update(locals())
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.