为何执行指定Bash脚本会意外截断当前目录的run.r2g.internal.sh文件?
cat run.r2g.internal.sh > "$(npm bin -g)/r2g" truncate the source file? Let's break down exactly what's tripping you up here—it's a classic shell gotcha tied to how Bash handles redirections, paired with an unexpected overlap between your target path and the source file.
Here's the core issue: Bash processes redirections before executing the actual command. When you run cat source > target, Bash doesn't first read the entire source file and then write to the target. Instead, it immediately opens the target file for writing (which truncates it if it already exists) before launching cat to read the source.
Now, the critical piece: "$(npm bin -g)/r2g" is pointing directly to your run.r2g.internal.sh file. This could happen for a couple common reasons:
- You might have accidentally set your global npm
bindirectory to your current working directory (vianpm config set prefix). - More likely,
r2gis a symbolic link that points back torun.r2g.internal.shin your current folder, or it's a hard link (same underlying file) created from a previous copy.
So when Bash processes the redirection, it opens $(npm bin -g)/r2g for writing—which truncates it. But since that file is actually your run.r2g.internal.sh, you're wiping out the source file before cat can even read it. That's why the file gets emptied, and why removing that line stops the problem entirely.
Fixes to avoid this
You have two straightforward ways to prevent this:
- Use
cpinstead ofcat—it's purpose-built for copying files safely, and it handles reading the source fully before writing to the target:cp run.r2g.internal.sh "$(npm bin -g)/r2g" - Use a temporary file as an intermediary if you prefer sticking with
cat:temp_file=$(mktemp) cat run.r2g.internal.sh > "$temp_file" mv "$temp_file" "$(npm bin -g)/r2g"
Either approach ensures your source file isn't truncated before it's read.
内容的提问来源于stack exchange,提问作者user7898461

