请有人检查我的代码以了解为什么我会得到
意外标记附近有语法错误
('
我已经运行过这段代码几次但都得到同样的错误
#!/bin/bash
vcf_file_dir="/10/"
project_output_path="$(pwd)"
my_samples_list=("1002793") # Add your actual sample IDs
for sample_id in "${my_samples_list[@]}"; do
# Print the sample you're retrieving data for
echo "Retrieving file for sample: ${sample_id}"
# Create a command to get the VCF header and save it to header.txt
my_command="bcftools view -h ${vcf_file_dir}/${sample_id}_file.vcf > header.txt"
# Launch the job with needed input files and command
dx run swiss-army-knife \
-iin="${vcf_file_dir}/${sample_id}_.vcf.gz" \
-iin="${vcf_file_dir}/${sample_id}_.vcf.gz.tbi" \
-icmd="${my_command}" \
--tag "my_job_name_${sample_id}" \
--instance-type "mem2_ssd1_v2_x64" \
--destination="${project_output_path}" \
--priority high \
--yes \
done
答案1
我不知道该怎么dx run swiss-army-knife
做,但是你传递了-icmd="${my_command}"
,其中${my_command}
扩展为字符串,其中已经扩展${vcf_file_dir}
了。其中包含了(VCFs)
更多内容。
从您尝试传递的内容来看-icmd=
,我推断它应该是 shell 代码,就像某些东西sh -c
会接受一样。如果是这样,您需要在代码中嵌入必要的引号来构建它。
具体来说,您要传递的是:
bcftools view -h mnt/project/Bulk/DRAGEN WGS/Whole genome variant call files (VCFs) (DRAGEN) [500k release]/10//1002793_file.vcf > header.txt
有未加引号的空格,(VCFs)
看起来(DRAGEN)
像是意外位置的子 shell(这就是“意外标记(
”的来源),并且[500k release]
是文件名生成模式。正确加引号将修复此问题。Bash 可以为您加引号。
${parameter@operator}
扩展是参数值的变换或参数本身的信息,具体取决于 的值operator
。每个operator
都是一个字母:[…]
Q
扩展是一个字符串,它是参数的值,以可重复用作输入的格式引用。
(来源)
“可以重复用作输入”,我认为这正是您想要做的。因此,在您构建的位置my_command
,应该是:
my_command="bcftools view -h ${vcf_file_dir@Q}/${sample_id@Q}_file.vcf > header.txt"
现在如果你printf '%s\n' "$my_command"
这样做的话,你会看到它是一个正确引用的 shell 代码。
@Q
是 bash-4.4-alpha 中引入的功能。旧版本的 Bash 可以使用以下格式实现类似的%q
效果printf
:
my_command="bcftools view -h $(printf %q "$vcf_file_dir")/$(printf %q "$sample_id")_file.vcf > header.txt"
也许某些非常老版本的 Bash 包含printf
无法识别的内置函数%q
,我不知道。如果这是个问题,请尝试使用外部函数printf
(如/usr/bin/printf
)。只有当这不起作用时,才手动添加单引号。但请注意,只有当变量的值完全在您的控制之下并且它们不包含单引号时,这种简单的修复才是安全的:
# FLAWED in general
my_command="bcftools view -h '${vcf_file_dir}/${sample_id}_file.vcf' > header.txt"
看起来,所讨论的变量满足这些要求。但是,一般来说,如果恶意用户或程序可以影响任何变量,他们就可以注入任意 shell 代码(例如,$my_command
如果 的内容$vcf_file_dir
实际上是,则查看 的内容是什么'& rm -f important_file& '
)。这是手动添加单引号的缺陷。即使在这种情况下,带有 的方法@Q
和带有 的方法也printf %q
应该是安全的。
附注:您的代码包含一个 shebang,但在注释中您承认您使用 运行代码。请注意,当您运行这样的脚本时,shebang 并不重要。如果您运行左右bash code.sh
,shebang 就会很重要。./code.sh