Bash脚本中git clone含%20的URL执行失败问题排查
git clone fail in my bash script but work when run directly? Let's break down exactly what's going wrong here and how to fix it:
Core Issues
Your script has three key problems that are causing the git clone failure:
1. Your url variable includes extra double quotes
You mentioned that echo $url outputs "https://gitprovider.com/Example/_git/Repo%20Name" (with surrounding quotes). That means your cli-tool is returning the URL wrapped in double quotes, and those quotes are being stored directly in the url variable. When you pass this to git clone without removing them, git treats the quotes as part of the repository path—so it tries to create a directory named Repo%20Name" (with a trailing quote), which is invalid on most systems (hence the "Invalid argument" error).
2. You're incorrectly using command substitution $()
Writing $(git clone ${url}) tells bash to capture the output of git clone and then execute that output as a new shell command. That's totally unnecessary here—git clone is a command you want to run directly, not capture output from. This extra layer of command substitution is only adding unexpected behavior.
3. You're not quoting your variable reference
Even if the quotes weren't an issue, using ${url} without wrapping it in double quotes ("$url") lets bash split the URL into separate arguments if it contains spaces or special characters. While %20 is URL-encoded, unquoted variables are still subject to bash's word splitting rules, which can break the URL structure.
Fixed Script
Here's how to adjust your script to fix all these issues:
#!/bin/bash function clone { # Strip the extra double quotes from the cli-tool output url=$(cli-tool "$1" that finds url | tr -d '"') echo "$url" # Run git clone directly, with quoted variable git clone "$url" }
Step-by-Step Explanation
- Remove unwanted quotes: The
tr -d '"'command strips all double quotes from thecli-tooloutput, sourlnow holds the clean, unquoted URL:https://gitprovider.com/Example/_git/Repo%20Name. - Drop command substitution: We just run
git clonedirectly—no need for$()here. This lets git execute normally without bash trying to re-run its output. - Quote the variable: Wrapping
$urlin double quotes ("$url") ensures bash passes the entire URL as a single, intact argument togit clone, just like when you run the command manually in your terminal.
This matches the manual behavior you know works, and eliminates the parsing errors that were breaking your script.
内容的提问来源于stack exchange,提问作者Tulsi Leathers

