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.