Skip to content

Unescaped quotes in generated bash shell script #3297

@prs513rosewood

Description

@prs513rosewood

Snakemake version

8.27.1

Describe the bug

When using the shell directive (bash script) with the config directive, associative arrays are added to a generated shell script. If a string in the config YAML file contains ' then the generated associative arrays contain unescaped double-quotes which causes a syntax error.

Logs

Building DAG of jobs...
Using shell: /usr/bin/bash
Provided cores: 20
Rules claiming more threads will be scaled down.
Job stats:
job      count
-----  -------
test         1
total        1

Select jobs to execute...
Execute 1 jobs...

[Mon Feb 17 11:09:53 2025]
localrule test:
    output: test.txt
    jobid: 0
    reason: Forced execution
    resources: tmpdir=/tmp

/home/rosewood/Desktop/snakemake_shell/.snakemake/scripts/tmpz6rzz406.script.sh: line 9: unexpected EOF while looking for matching `''
/home/rosewood/Desktop/snakemake_shell/.snakemake/scripts/tmpz6rzz406.script.sh: line 13: syntax error: unexpected end of file
Not cleaning up /home/rosewood/Desktop/snakemake_shell/.snakemake/scripts/tmpz6rzz406.script.sh
RuleException:
CalledProcessError in file /home/rosewood/Desktop/snakemake_shell/Snakefile, line 9:
Command 'set -euo pipefail;  bash /home/rosewood/Desktop/snakemake_shell/.snakemake/scripts/tmpz6rzz406.script.sh' returned non-zero exit status 1.
[Mon Feb 17 11:09:53 2025]
Error in rule test:
    jobid: 0
    output: test.txt

Shutting down, this might take some time.
Exiting because a job execution failed. Look above for error message
Complete log: .snakemake/log/2025-02-17T110953.594439.snakemake.log
WorkflowError:
At least one job did not complete successfully.

Minimal example

Snakefile

configfile: 'config.yaml'

rule test:
    output:
        'test.txt'
    params:
        d={'a': "foo'"}
    script:
        "script.sh"

script.sh

#!/usr/bin/env bash

echo "hello" > "${snakemake_output[0]}"

config.yaml

foo:
  bar: "let's go"

Run command snakemake test.txt --skip-script-cleanup -f

Additional context

Here is the generated bash script:

#!/usr/bin/env bash

declare -A snakemake_input=( )
declare -A snakemake_output=( [0]="test.txt" )
declare -A snakemake_params=( [0]="a" [d]="a" )
declare -A snakemake_wildcards=( )
declare -A snakemake_resources=( [0]="1" [_cores]="1" [1]="1" [_nodes]="1" [2]="/tmp" [tmpdir]="/tmp" )
declare -A snakemake_log=( )
declare -A snakemake_config=( [foo]="{'bar': "let's go"}" )
declare -A snakemake=( [_params_types]="{}" [threads]="1" [rule]="test" [bench_iteration]="None" [scriptdir]="/home/rosewood/Desktop/snakemake_shell" )

echo "hello" > "${snakemake_output[0]}"

Culprit is declare -A snakemake_config=( [foo]="{'bar': "let's go"}" ). Note that the snakemake_params is also incorrect.

Potential patch
I've tried the following fix, which solves the above MWE but may incorrectly escape double quotes.

diff --git a/snakemake/script/__init__.py b/snakemake/script/__init__.py
index c802bc15..4a70c41b 100644
--- a/snakemake/script/__init__.py
+++ b/snakemake/script/__init__.py
@@ -468,7 +468,8 @@ class BashEncoder:
         """Converts a dictionary to an associative array"""
         s = "( "
         for k, v in d.items():
-            s += f'[{k}]="{v}" '
+            formatted_v = f"{v}".replace('"', '\\"')
+            s += f'[{k}]="{formatted_v}" '
 
         s += ")"
         return s

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions