0

My python scripy print a string by print("declare -A gaps=( [2019-2-24]=4 )") and I can run declare -A gaps=( [2019-2-24]=4 ) on a bash shell to create a dictionary named gaps.

In my bash script, I use a variable named gap_string to access the output of python scripy. Then I use backquote surrounded the gap_string expected to create a dictionary which failed got and error: declare: “[2019-2-24]=4”: is not a valid identifier.

More details:

code in my bash script:

declare -A birthdays=(["${year}0120"]="GG")

gap_string=`/home/roach/.config/argos/LunarSolarConverter.py ${!birthdays[@]}`
if [ $? -eq 0 ]; then
    `$gap_string`
fi

code in my Python script:

if __name__ == '__main__':
    converter = LunarSolarConverter()
    gaps_string = ["declare -A gaps=("]
    today = datetime.datetime.today()
    today_date = today.date()
    year = today.year
    isleap = (year % 4 == 0 and (year % 100 != 0 or year % 400 == 0))
    days_this_year = 366 if isleap else 365
    for i in range(1, len(sys.argv)):
        year, month, day = int(sys.argv[i][:-4]), int(sys.argv[i][-4:-2]), int(sys.argv[i][-2:])
        lunar = Lunar(year, month, day, isleap)
        solar = converter.LunarToSolar(lunar)
        gap = (datetime.date(solar.solarYear, solar.solarMonth, solar.solarDay) - today_date).days % days_this_year
        if gap <= 4:
            gaps_string.append(f"[{solar.solarYear}-{solar.solarMonth}-{solar.solarDay}]={gap}")
    gaps_string.append(")")
    if len(gaps_string) == 2:
        sys.exit(1)
    else:
        print(" ".join(gaps_string))
        sys.exit(0)

What python script do is change Chinese lunardate to solardate, and then calculate the days between today and the specific solardate, and then to remind my family members' birthday to me.

  • 1
    I think you should add more info like how you assigned value into gap_string. And also the code Then I use backquote surrounded the gap_string expected to create a dictionary – Prvt_Yadv Feb 19 at 17:17
  • @PRY Hi, thanks for your advice, I updated more details! – roachsinai Feb 19 at 17:27
  • @PRY declare -A gaps=( [2019-2-24]=4 ) got this. – roachsinai Feb 19 at 17:39
1

Using backticks is wrong: that will attempt to execute the string like an external command. But the string is a bash specific command, and has be be executed in the context of the current shell. There are 2 ways to do this:

  1. use eval with a Command Substitution

    gaps=$( your_python_command )
    eval "$gaps"
    # or, the variable is unnecessary:
    eval "$( your_python_command )"
    
  2. use source with a Process Substitution

    source <( your_python_command )
    

In both cases, you better be sure you know what the python script is outputting: you don't want to execute any untrusted code.

  • Thanks for your reply! First method worked. I alse tested source < ( python /home/roach/.config/argos/LunarSolarConverter.py ${!birthdays[@]} ) got an error: Unexpected symbol "(" has a syntax error nearby. – roachsinai Feb 19 at 18:11
  • 1
    No space between the < and the ( – glenn jackman Feb 19 at 18:24
0

You can use set -x command for debugging. Take the below exmple:

set -x
declare -A gaps=( [2017-02-11]=4 )

Will give you:

+ gaps=([2017-02-11]=4)
+ declare -A gaps

And

s="declare -A gaps=( [2017-02-11]=4 )"
$s

Will give you:

+ declare -A 'gaps=(' '[2017-02-11]=4' ')'

So you can see that in the second case commands which are executing are:

declare -A 'gaps=('
declare -A [2017-02-11]=4
declare -A )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.