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.

3
  • 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_Yadav
    Feb 19, 2019 at 17:17
  • @PRY Hi, thanks for your advice, I updated more details!
    – roachsinai
    Feb 19, 2019 at 17:27
  • @PRY declare -A gaps=( [2019-2-24]=4 ) got this.
    – roachsinai
    Feb 19, 2019 at 17:39

2 Answers 2

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.

2
  • 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, 2019 at 18:11
  • 1
    No space between the < and the ( Feb 19, 2019 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 )

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .