Score:0

UnicodeEncodeError: 'utf-8' codec can't encode characters in position 4-6: surrogates not allowed

co flag

I have written a small code snippet to check the aws cli version

#!/bin/bash
if [ -e "/usr/local/bin/aws" ];
then
    myAWS="/usr/local/bin/aws"
else
    myAWS="/usr/bin/aws"
fi

myCmd=("${myAWS} --version")

echo "$myCmd"

message=$($myCmd)

echo "$message"

Now while running this manually with root user I am able to run but after our aws cli upgrade while running this via crontab

57 21 * * * /rough/scripts/log/test.sh > /rough/scripts/log/test.log 2>&1 

I face the below error , can you suggest , i have reinstalled the aws cli but to no effect.

/usr/local/bin/aws --version
Traceback (most recent call last):
  File "aws", line 19, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller/loader/pyimod02_importers.py", line 493, in exec_module
  File "awscli/clidriver.py", line 43, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller/loader/pyimod02_importers.py", line 493, in exec_module
  File "awscli/help.py", line 20, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller/loader/pyimod02_importers.py", line 493, in exec_module
  File "docutils/core.py", line 23, in <module>
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "PyInstaller/loader/pyimod02_importers.py", line 493, in exec_module
  File "docutils/io.py", line 43, in <module>
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 4-6: surrogates not allowed
[24036] Failed to execute script 'aws' due to unhandled exception!
waltinator avatar
it flag
`cron` runtime environment is different. see https://unix.stackexchange.com/questions/673908/why-crontab-doesnt-execute-a-scheduled-bash-script/673918#673918
AashkaTe avatar
co flag
Thanks @waltinator, is there a way I can check the current crontab runtime enviroment ?
hr flag
Is it possible that an aws configuration file in your profile (~/.aws/config, ~/.aws/credentials etc.) has a non UTF-8 encoding and your local environment handles that by setting `PYTHONIOENCODING` for example?
AashkaTe avatar
co flag
hi @steeldriver- I checked the ./aws/config file ----cat ~/.aws/config [default] s3 = signature_version = s3v4 region=eu-west-1 I am confused that if i run the script manually it runs fine but crontab is giving me the problem, any suggestions that can help surpass this error
terdon avatar
cn flag
May I ask what the point of the script is? I mean, why bother having the `if` to check two directories that are already in your `$PATH`? The whole script looks like it can be simplified to just the single command `aws --version`. Is it that you want to always prioritize the version found in `/usr/local/bin/` even if there is another in `/usr/bin/`? And why do `message=$(command); echo $message` instead of simply just running `command` directly?
Score:0
cn flag

Cron has its own PATH which is hardcoded in the source code. This means that cron commands will run in a different environment. My guess is that your user (or root) are configured with a different python in their PATH. Or maybe you activate a python environment on login, or have installed some pip packages. Whatever the case may be, you will need to reproduce that in your cron.

First, run echo "$PATH" while logged in as the user for whom the command works. Then, take the PATH that prints and add it to the beginning of the crontab:

PATH="blah;blah;blah"
57 21 * * * /rough/scripts/log/test.sh > /rough/scripts/log/test.log 2>&1 

If that doesn't work, you can try loading the user's shell configuration file with bash -i:

       -i        If the -i option is present, the shell is interactive.

That will force bash to run in "interactive" mode, meaning it will read the invoking user's ~/.bashrc file (see https://askubuntu.com/a/438170/85695):

57 21 * * * bash -i /rough/scripts/log/test.sh > /rough/scripts/log/test.log 2>&1 

If that still doesn't work, you will need to figure out exactly what python setup you are using and where it comes from and try to reproduce that in the crontab. If you edit your question with more detail about your setup we might be able to help.


On an unrelated note, you could simplify your script a little. First, since both /usr/local/bin and /usr/bin are in the default PATH, if the objective of your if is to find which of the two contains an aws executable, then you don't need the if at all and can simply run aws.

If instead you want to always prioritize the version in /usr/local/bin even if there is another one in /usr/bin, then the if makes sense.

Next, there's not much point in running message=$(command); echo $message: if command prints out what you want to see, just run it directly. I would write your script like this instead:

#!/bin/bash
myAws=/usr/bin/aws
[ -e /usr/local/bin/aws ] && myAws=/usr/local/bin/aws

myCmd=("$myAWS" "--version")
echo "${myCmd[@]}"
"${myCmd[@]}"

Or, if you just want to run an aws and the if was only to figure out where it is installed, and you also want to see the full path to it, simply:

#!/bin/bash
myAws=$(which aws)
myCmd=("$myAws" "--version")
echo "${myCmd[@]}"
"${myCmd[@]}"
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.