bash脚本中for循环搭配nohup执行异常问题求助
Let's break down why your script is failing under nohup and fix it step by step. The core issue here is almost certainly related to how nohup interacts with the shell, or unhandled errors in your script that don't surface under qsub.
Most Likely Culprit: Nohup Uses sh Instead of bash
Your script relies on bash-specific syntax: the brace expansion {1..20..1}. Many systems configure nohup to run scripts with /bin/sh by default, and sh doesn't support this brace expansion. Instead of looping 20 times, it treats {1..20..1} as a single literal value—so the loop runs once, none of your if/elif conditions match, it executes ./compiled_code one time, and exits.
Fix 1: Force Nohup to Use Bash
Run your script explicitly with bash instead of relying on the shebang alone, and redirect output to a log file for debugging:
nohup bash your_script.sh > script.log 2>&1 &
The > script.log 2>&1 part captures both standard output and errors, so you can trace exactly what's happening if issues persist.
Unhandled Script Errors
Under qsub, the job environment might be more forgiving, but nohup could exit silently if a command fails (like mv failing because output doesn't exist on the first iteration).
Fix 2: Add Strict Error Handling
Add these lines right after the shebang in your script to make errors visible and stop execution immediately when something goes wrong:
set -euo pipefail
set -e: Exit the script if any command failsset -u: Throw an error if an undefined variable is usedset -o pipefail: Make pipelines fail if any command in them fails
This will force the script to log exactly where it failed, so you can pinpoint issues like missing files or incorrect variable values.
Optimize Your Script (Eliminate Redundant if/elif Chains)
Your current if/elif chain is repetitive and error-prone (especially with 20 iterations). Instead, calculate the seed dynamically to simplify the code and reduce bugs:
Improved Script
#!/bin/bash set -euo pipefail # Switch to the script's directory to avoid path-related issues cd "$(dirname "$0")" current_seed=0 # Assume your initial input file has seed=0 for number in {1..20}; do new_seed=$((number * 100)) # Update the seed in input (creates a .bak backup file as a safety net) sed -i.bak "s/seed=$current_seed/seed=$new_seed/" input # Rename the previous output (only if it exists) if [ "$number" -gt 1 ]; then mv -f output "output$((number - 1))" fi # Run your compiled program ./compiled_code < input > output # Prepare the seed value for the next iteration current_seed=$new_seed done # Rename the final output file mv -f output output20 # Optional: Clean up the backup file created by sed rm -f input.bak
Key improvements here:
- Dynamic seed calculation removes 18 redundant
elifblocks sed -i.bakmodifies the input file directly safely (with a backup)mv -favoids errors if the output file doesn't exist on the first runcd "$(dirname "$0")"ensures the script runs in its own directory, even if you launch it from elsewhere
Verify Working Directory
If your input file or compiled_code aren't in the directory where you run nohup, the script will fail silently. The cd line in the improved script fixes this by switching to the script's directory automatically.
内容的提问来源于stack exchange,提问作者Skeptical Khan

