Backing up dotfiles with a shell script
Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
A simple shell script is needed to copy dotfiles, adding a .backup extension, i.e., .dotfile1.backup. The script below will not work because it adds extensions to pre-existing backups forever and ever, i.e., .dotfile1.backup.backup.
bkdot.sh
#!/bin/sh
for file in .*; do
cp “./$file” “./$file.backup”
done
The next script seems like it should solve the problem, but nothing happens at all. What is it missing?
bkdot_revised.sh
#!/bin/sh
for file in .*; do
if [ ! “./$file.backup” ]; then
cp “./$file” “./$file.backup”
fi
done
shell-script shell
add a comment |
up vote
0
down vote
favorite
A simple shell script is needed to copy dotfiles, adding a .backup extension, i.e., .dotfile1.backup. The script below will not work because it adds extensions to pre-existing backups forever and ever, i.e., .dotfile1.backup.backup.
bkdot.sh
#!/bin/sh
for file in .*; do
cp “./$file” “./$file.backup”
done
The next script seems like it should solve the problem, but nothing happens at all. What is it missing?
bkdot_revised.sh
#!/bin/sh
for file in .*; do
if [ ! “./$file.backup” ]; then
cp “./$file” “./$file.backup”
fi
done
shell-script shell
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
A simple shell script is needed to copy dotfiles, adding a .backup extension, i.e., .dotfile1.backup. The script below will not work because it adds extensions to pre-existing backups forever and ever, i.e., .dotfile1.backup.backup.
bkdot.sh
#!/bin/sh
for file in .*; do
cp “./$file” “./$file.backup”
done
The next script seems like it should solve the problem, but nothing happens at all. What is it missing?
bkdot_revised.sh
#!/bin/sh
for file in .*; do
if [ ! “./$file.backup” ]; then
cp “./$file” “./$file.backup”
fi
done
shell-script shell
A simple shell script is needed to copy dotfiles, adding a .backup extension, i.e., .dotfile1.backup. The script below will not work because it adds extensions to pre-existing backups forever and ever, i.e., .dotfile1.backup.backup.
bkdot.sh
#!/bin/sh
for file in .*; do
cp “./$file” “./$file.backup”
done
The next script seems like it should solve the problem, but nothing happens at all. What is it missing?
bkdot_revised.sh
#!/bin/sh
for file in .*; do
if [ ! “./$file.backup” ]; then
cp “./$file” “./$file.backup”
fi
done
shell-script shell
shell-script shell
edited Dec 7 at 15:05
asked Dec 7 at 6:57
justinnoor.io
350218
350218
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
1
down vote
The !
operator just negates it's operand so the condition always evaluates to false
.
There are file test operators, -f
for instance that returns true if file exists.
However I'm not sure you are doing this right, neither only making backup if it doesn't exist nor always overwriting existing backups is secure.
Could do this way.
#!/bin/sh
for file in .*; do
if [ ! -f "./$file.backup" ]; then
cp "./$file" "./$file.backup"
fi
done
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
add a comment |
up vote
1
down vote
The test [
doesn't have enough information. You need to compare $file
to a reference. You current construct says "if not this string", but you need to say "if x is not this string". I would use a regex, i.e. with [[
instead of [
. Hence,
#!/bin/bash
GLOBIGNORE=.:..
for file in .*; do
if [[ ! "$file" =~ .backup$ ]]; then
cp "$file" "$file.backup"
fi
done
- As per Kusalananda's comment, I moved the shebang to
/bin/bash
, to ensure the[[
construct works. - As per Gordon Davisson's comment, I added the
GLOBIGNORE
, so that the script doesn't attempt to copy.
and..
A few other things:
./
in the paths is unnecessary. You are already in this directory!- I'm not sure if it was just a copy-paste issue, but you had
“
instead of"
. - Personally, I would just copy into another directory, and avoid all these issues, and avoid polluting my home directory. Actually, I would just (incrementally) backup everything instead!
Here is a pure /bin/sh
version. Instead of using the [[
bashism, I've used case instead.
#!/bin/sh
GLOBIGNORE=.:..
for file in .*; do
case "$file" in
*.backup) ;;
*) cp "$file" "$file.backup";;
esac
done
1
Also, this will try to back up.
(the entire current directory) and..
(its parent), along with any dot directories (e.g..ssh
)... but fail becausecp
requires the-R
option to do this.
– Gordon Davisson
Dec 7 at 7:29
@GordonDavisson Good point. I was actually testing withzsh
, silly me. I've edited the answer.
– Sparhawk
Dec 7 at 8:07
1
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +.backup
. It's a bit unclear, but if there were.foo
, then.foo.backup
were created, then.foo
deleted,-f
would result in.foo.backup.backup
being created… which I assume is not preferred.
– Sparhawk
Dec 7 at 8:12
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to/bin/sh
, my script still works. It may well work on yours too.
– Sparhawk
Dec 7 at 23:08
|
show 2 more comments
up vote
0
down vote
Why don't we simply use sed
to backup?
sed -i.bak 's#n#n#' <filepattern*>
add a comment |
Your Answer
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "106"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f486520%2fbacking-up-dotfiles-with-a-shell-script%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
The !
operator just negates it's operand so the condition always evaluates to false
.
There are file test operators, -f
for instance that returns true if file exists.
However I'm not sure you are doing this right, neither only making backup if it doesn't exist nor always overwriting existing backups is secure.
Could do this way.
#!/bin/sh
for file in .*; do
if [ ! -f "./$file.backup" ]; then
cp "./$file" "./$file.backup"
fi
done
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
add a comment |
up vote
1
down vote
The !
operator just negates it's operand so the condition always evaluates to false
.
There are file test operators, -f
for instance that returns true if file exists.
However I'm not sure you are doing this right, neither only making backup if it doesn't exist nor always overwriting existing backups is secure.
Could do this way.
#!/bin/sh
for file in .*; do
if [ ! -f "./$file.backup" ]; then
cp "./$file" "./$file.backup"
fi
done
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
add a comment |
up vote
1
down vote
up vote
1
down vote
The !
operator just negates it's operand so the condition always evaluates to false
.
There are file test operators, -f
for instance that returns true if file exists.
However I'm not sure you are doing this right, neither only making backup if it doesn't exist nor always overwriting existing backups is secure.
Could do this way.
#!/bin/sh
for file in .*; do
if [ ! -f "./$file.backup" ]; then
cp "./$file" "./$file.backup"
fi
done
The !
operator just negates it's operand so the condition always evaluates to false
.
There are file test operators, -f
for instance that returns true if file exists.
However I'm not sure you are doing this right, neither only making backup if it doesn't exist nor always overwriting existing backups is secure.
Could do this way.
#!/bin/sh
for file in .*; do
if [ ! -f "./$file.backup" ]; then
cp "./$file" "./$file.backup"
fi
done
answered Dec 7 at 7:51
ntj
164
164
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
add a comment |
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
This doesn’t solve the .backup.backup issue.
– justinnoor.io
Dec 7 at 15:38
add a comment |
up vote
1
down vote
The test [
doesn't have enough information. You need to compare $file
to a reference. You current construct says "if not this string", but you need to say "if x is not this string". I would use a regex, i.e. with [[
instead of [
. Hence,
#!/bin/bash
GLOBIGNORE=.:..
for file in .*; do
if [[ ! "$file" =~ .backup$ ]]; then
cp "$file" "$file.backup"
fi
done
- As per Kusalananda's comment, I moved the shebang to
/bin/bash
, to ensure the[[
construct works. - As per Gordon Davisson's comment, I added the
GLOBIGNORE
, so that the script doesn't attempt to copy.
and..
A few other things:
./
in the paths is unnecessary. You are already in this directory!- I'm not sure if it was just a copy-paste issue, but you had
“
instead of"
. - Personally, I would just copy into another directory, and avoid all these issues, and avoid polluting my home directory. Actually, I would just (incrementally) backup everything instead!
Here is a pure /bin/sh
version. Instead of using the [[
bashism, I've used case instead.
#!/bin/sh
GLOBIGNORE=.:..
for file in .*; do
case "$file" in
*.backup) ;;
*) cp "$file" "$file.backup";;
esac
done
1
Also, this will try to back up.
(the entire current directory) and..
(its parent), along with any dot directories (e.g..ssh
)... but fail becausecp
requires the-R
option to do this.
– Gordon Davisson
Dec 7 at 7:29
@GordonDavisson Good point. I was actually testing withzsh
, silly me. I've edited the answer.
– Sparhawk
Dec 7 at 8:07
1
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +.backup
. It's a bit unclear, but if there were.foo
, then.foo.backup
were created, then.foo
deleted,-f
would result in.foo.backup.backup
being created… which I assume is not preferred.
– Sparhawk
Dec 7 at 8:12
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to/bin/sh
, my script still works. It may well work on yours too.
– Sparhawk
Dec 7 at 23:08
|
show 2 more comments
up vote
1
down vote
The test [
doesn't have enough information. You need to compare $file
to a reference. You current construct says "if not this string", but you need to say "if x is not this string". I would use a regex, i.e. with [[
instead of [
. Hence,
#!/bin/bash
GLOBIGNORE=.:..
for file in .*; do
if [[ ! "$file" =~ .backup$ ]]; then
cp "$file" "$file.backup"
fi
done
- As per Kusalananda's comment, I moved the shebang to
/bin/bash
, to ensure the[[
construct works. - As per Gordon Davisson's comment, I added the
GLOBIGNORE
, so that the script doesn't attempt to copy.
and..
A few other things:
./
in the paths is unnecessary. You are already in this directory!- I'm not sure if it was just a copy-paste issue, but you had
“
instead of"
. - Personally, I would just copy into another directory, and avoid all these issues, and avoid polluting my home directory. Actually, I would just (incrementally) backup everything instead!
Here is a pure /bin/sh
version. Instead of using the [[
bashism, I've used case instead.
#!/bin/sh
GLOBIGNORE=.:..
for file in .*; do
case "$file" in
*.backup) ;;
*) cp "$file" "$file.backup";;
esac
done
1
Also, this will try to back up.
(the entire current directory) and..
(its parent), along with any dot directories (e.g..ssh
)... but fail becausecp
requires the-R
option to do this.
– Gordon Davisson
Dec 7 at 7:29
@GordonDavisson Good point. I was actually testing withzsh
, silly me. I've edited the answer.
– Sparhawk
Dec 7 at 8:07
1
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +.backup
. It's a bit unclear, but if there were.foo
, then.foo.backup
were created, then.foo
deleted,-f
would result in.foo.backup.backup
being created… which I assume is not preferred.
– Sparhawk
Dec 7 at 8:12
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to/bin/sh
, my script still works. It may well work on yours too.
– Sparhawk
Dec 7 at 23:08
|
show 2 more comments
up vote
1
down vote
up vote
1
down vote
The test [
doesn't have enough information. You need to compare $file
to a reference. You current construct says "if not this string", but you need to say "if x is not this string". I would use a regex, i.e. with [[
instead of [
. Hence,
#!/bin/bash
GLOBIGNORE=.:..
for file in .*; do
if [[ ! "$file" =~ .backup$ ]]; then
cp "$file" "$file.backup"
fi
done
- As per Kusalananda's comment, I moved the shebang to
/bin/bash
, to ensure the[[
construct works. - As per Gordon Davisson's comment, I added the
GLOBIGNORE
, so that the script doesn't attempt to copy.
and..
A few other things:
./
in the paths is unnecessary. You are already in this directory!- I'm not sure if it was just a copy-paste issue, but you had
“
instead of"
. - Personally, I would just copy into another directory, and avoid all these issues, and avoid polluting my home directory. Actually, I would just (incrementally) backup everything instead!
Here is a pure /bin/sh
version. Instead of using the [[
bashism, I've used case instead.
#!/bin/sh
GLOBIGNORE=.:..
for file in .*; do
case "$file" in
*.backup) ;;
*) cp "$file" "$file.backup";;
esac
done
The test [
doesn't have enough information. You need to compare $file
to a reference. You current construct says "if not this string", but you need to say "if x is not this string". I would use a regex, i.e. with [[
instead of [
. Hence,
#!/bin/bash
GLOBIGNORE=.:..
for file in .*; do
if [[ ! "$file" =~ .backup$ ]]; then
cp "$file" "$file.backup"
fi
done
- As per Kusalananda's comment, I moved the shebang to
/bin/bash
, to ensure the[[
construct works. - As per Gordon Davisson's comment, I added the
GLOBIGNORE
, so that the script doesn't attempt to copy.
and..
A few other things:
./
in the paths is unnecessary. You are already in this directory!- I'm not sure if it was just a copy-paste issue, but you had
“
instead of"
. - Personally, I would just copy into another directory, and avoid all these issues, and avoid polluting my home directory. Actually, I would just (incrementally) backup everything instead!
Here is a pure /bin/sh
version. Instead of using the [[
bashism, I've used case instead.
#!/bin/sh
GLOBIGNORE=.:..
for file in .*; do
case "$file" in
*.backup) ;;
*) cp "$file" "$file.backup";;
esac
done
edited Dec 7 at 23:50
answered Dec 7 at 7:19
Sparhawk
9,13863890
9,13863890
1
Also, this will try to back up.
(the entire current directory) and..
(its parent), along with any dot directories (e.g..ssh
)... but fail becausecp
requires the-R
option to do this.
– Gordon Davisson
Dec 7 at 7:29
@GordonDavisson Good point. I was actually testing withzsh
, silly me. I've edited the answer.
– Sparhawk
Dec 7 at 8:07
1
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +.backup
. It's a bit unclear, but if there were.foo
, then.foo.backup
were created, then.foo
deleted,-f
would result in.foo.backup.backup
being created… which I assume is not preferred.
– Sparhawk
Dec 7 at 8:12
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to/bin/sh
, my script still works. It may well work on yours too.
– Sparhawk
Dec 7 at 23:08
|
show 2 more comments
1
Also, this will try to back up.
(the entire current directory) and..
(its parent), along with any dot directories (e.g..ssh
)... but fail becausecp
requires the-R
option to do this.
– Gordon Davisson
Dec 7 at 7:29
@GordonDavisson Good point. I was actually testing withzsh
, silly me. I've edited the answer.
– Sparhawk
Dec 7 at 8:07
1
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +.backup
. It's a bit unclear, but if there were.foo
, then.foo.backup
were created, then.foo
deleted,-f
would result in.foo.backup.backup
being created… which I assume is not preferred.
– Sparhawk
Dec 7 at 8:12
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to/bin/sh
, my script still works. It may well work on yours too.
– Sparhawk
Dec 7 at 23:08
1
1
Also, this will try to back up
.
(the entire current directory) and ..
(its parent), along with any dot directories (e.g. .ssh
)... but fail because cp
requires the -R
option to do this.– Gordon Davisson
Dec 7 at 7:29
Also, this will try to back up
.
(the entire current directory) and ..
(its parent), along with any dot directories (e.g. .ssh
)... but fail because cp
requires the -R
option to do this.– Gordon Davisson
Dec 7 at 7:29
@GordonDavisson Good point. I was actually testing with
zsh
, silly me. I've edited the answer.– Sparhawk
Dec 7 at 8:07
@GordonDavisson Good point. I was actually testing with
zsh
, silly me. I've edited the answer.– Sparhawk
Dec 7 at 8:07
1
1
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +
.backup
. It's a bit unclear, but if there were .foo
, then .foo.backup
were created, then .foo
deleted, -f
would result in .foo.backup.backup
being created… which I assume is not preferred.– Sparhawk
Dec 7 at 8:12
@Kusalananda Thanks. Edited. Yeah, I interpreted the test in the question as looking for the current filename's suffix, rather than testing for a copy of the current file +
.backup
. It's a bit unclear, but if there were .foo
, then .foo.backup
were created, then .foo
deleted, -f
would result in .foo.backup.backup
being created… which I assume is not preferred.– Sparhawk
Dec 7 at 8:12
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
It’s not a bash script
– justinnoor.io
Dec 7 at 14:00
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to
/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to /bin/sh
, my script still works. It may well work on yours too.– Sparhawk
Dec 7 at 23:08
@justinnoor.io What do you mean? This is a bash script. Or are you saying that you do not want a bash script? Your shebang refers to
/bin/sh
, but depending on the system, this can be ambiguous. On my system (Arch Linux), if I change the shebang to /bin/sh
, my script still works. It may well work on yours too.– Sparhawk
Dec 7 at 23:08
|
show 2 more comments
up vote
0
down vote
Why don't we simply use sed
to backup?
sed -i.bak 's#n#n#' <filepattern*>
add a comment |
up vote
0
down vote
Why don't we simply use sed
to backup?
sed -i.bak 's#n#n#' <filepattern*>
add a comment |
up vote
0
down vote
up vote
0
down vote
Why don't we simply use sed
to backup?
sed -i.bak 's#n#n#' <filepattern*>
Why don't we simply use sed
to backup?
sed -i.bak 's#n#n#' <filepattern*>
answered Dec 7 at 7:44
msp9011
3,65543863
3,65543863
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f486520%2fbacking-up-dotfiles-with-a-shell-script%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown