简体   繁体   中英

Is it possible in a bash script to change it's content while it's running?

Short version: Is it possible in a bash script to change it's content while it's running?

Long version: I have a bash script that i want to change it's EOL from CRLF'\\r\\n' to LF'\\n' while it's running. At the moment, what i could manage to do so far is to put this line on top of the script:

sed -i -e "s/\r$//g; s/^sed -i -e/#sed -i -e/g" $(basename $0); echo "Rerun again.." ; exit 0;

But it's unpractical for sure.

I was thinking of that When the script runs in the first line it creates a subshell and puts the content of the current shell there, do some changes and put it back in the upper shell. Is that possible somehow?

or

Do the same idea, but to create a copy of the current script in a new temp script:

cat $0 > temp.sh

Then the main script will execute temp.sh, after the script finishes, it catches the copy of temp.sh back to the main script and removes temp.sh. I think this works in theory, but I'm sure there is some easier way.

NOTE: This is not about EOL particularly, I have some scripts that I need to apply same functionality to.

Example of usage: The project involves running the script on windows and linux, if any user opened the script by editor on Windows, it will save the EOL to windows format which is '\\n\\r', this will give this error on windows:

./script.sh: line 5: syntax error near unexpected token `$'{\r''
'/script.sh: line 5: `foo(){

And that's why i used sed in the beginning of the script.

Do not change the currently running script.

Once I had a very slow script and during executing I started to tweak it to prepare for the next execution. It started to behave very strangely. It seems to me bash only reads the beginning of the script and reads the other parts later. So it was not a problem at the beginning when my script was short but as my script became longer it started to cause problems.

You could extend your current attempt:

[[ -z "$CANARY" ]] && { sed -i -e 's/\r$//g' "${BASH_SOURCE[0]}"; CANARY=1 exec "${BASH_SOURCE[0]}"; }

Essentially, you test for some variable, do your modification and then re-exec using the modified source while setting the variable.

You could also source it instead of exec ing, and not modify the actual script file:

[[ -z "$CANARY" ]] && { CANARY=1 source <(sed 's/\r$//g' "${BASH_SOURCE[0]}"); exit }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM