Issue
I am trying to pass the output of a shell script into python, it works when I do not have unicode characters inside the string that should be returned. The bash script that gets the currently played music:
player_status=$(playerctl status 2> /dev/null)
if [[ $? -eq 0 ]]; then
metadata="$(playerctl metadata title 2> /dev/null)"
else
metadata="No music playing"
fi
# Foreground color formatting tags are optional
if [[ $player_status = "Playing" ]]; then
echo "$metadata"|cut -c -65 # when playing
elif [[ $player_status = "Paused" ]]; then
echo "$metadata"|cut -c -65 # when paused
else
echo "$metadata"|cut -c -65 # when stopped
fi
The python script that uses the return value of the script above
def getMusicName():
music_name = os.popen('bash /home/nep/Self\ Script/now-playing.sh').read()
return music_name
The error
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 64: invalid continuation byte
Finally the name of the music that it was trying to decode:
IZANAGI 【 イザナギ 】 ☯ Japanese Trap & Bass Type Beat ☯ Trapanese Hip Hop Mix
As a sidenote, this is on a Linux system, but I do not think it should make a difference, also if I run the shell script alone it returns the name like this:
IZANAGI 【 イザナギ 】 ☯ Japanese Trap & Bass Type Beat �
⏎
Solution
To be sure the metadata is using proper UTF-8 encoding, you can filter the output of playerctl
with iconv -ct UTF-8//TRANSLIT
:
Here is your improved script:
#!/usr/bin/env bash
if player_status="$(playerctl status 2>/dev/null)"; then
metadata="$(playerctl metadata title 2>/dev/null | iconv -ct UTF-8//TRANSLIT)"
else
metadata="No music playing"
fi
# Foreground color formatting tags are optional
case "$player_status" in
Playing)
printf '%.65s\n' "$metadata" # when playing
;;
Paused)
printf '%.65s\n' "$metadata" # when paused
;;
*)
printf '%.65s\n' "$metadata" # when stopped
;;
esac
Answered By - Léa Gris Answer Checked By - Mary Flores (WPSolving Volunteer)