Is it possible to create a script to save and restore permissions?
hm. so you need to
1) read file permissions
2) store them somehow, associated to each file
3) read your stored permissions and set them back
not a complete solution but some ideas:
stat -c%a filename
>644
probably in combination with
find -exec
to store this information, this so question has some interesting ideas. basically you create a temporary file structure matching your actual files, with each temp file containing the file permissions
to reset you iterate over your temp files, read permissions and chmod the actual files back.
How to backup and restore permission with certain order and can be compared to find the difference?
If anything can be improved,such as add print0
,pls comment or create a new answer.
find * -depth -exec stat --format '%a %U %G %n' {} + > ../repo/all_folders_files_permission
while read PERMS OWNER GROUP FILE
do
chmod "$PERMS" "$FILE"
chown "${OWNER}:${GROUP}" "$FILE"
done < ../repo/all_folders_files_permission
backup and restore permissions
List format is okay for human readers, but it's not really suitable for restoring data from a file. Save the full path and SDDL of each folder to a CSV:
foreach ($Folder in $FolderList) {
Get-Acl $folder | Select-Object @{n='Path';e={$Folder.FullName}}, Sddl |
Export-Csv $OutputFile -NoType -Append
...
}
That should allow you to restore the security information like this:
Import-Csv $OutputFile | ForEach-Object {
$acl = Get-Acl -Path $_.Path
$acl.SetSecurityDescriptorSddlForm($_.Sddl)
Set-Acl -Path $_.Path -AclObject $acl
}
Saving and restoring ACLs
To answer my own question, I've found a program named AccessEnum that lists all the folders that have different permissions than the parent.
http://technet.microsoft.com/en-us/sysinternals/bb897332.aspx
This has allowed me to identify which folders need write or write/execute permissions and apply them by hand.
It's not ideal but the other alternative was also time consuming and somewhat complex.
How to restore the permissions of files and directories within git if they have been modified?
Git keeps track of filepermission and exposes permission changes when creating patches using git diff -p
. So all we need is:
- create a reverse patch
- include only the permission changes
- apply the patch to our working copy
As a one-liner:
git diff -p -R --no-ext-diff --no-color \
| grep -E "^(diff|(old|new) mode)" --color=never \
| git apply
you can also add it as an alias to your git config...
git config --global --add alias.permission-reset '!git diff -p -R --no-ext-diff --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply'
...and you can invoke it via:
git permission-reset
Note, if you shell is bash
, make sure to use '
instead of "
quotes around the !git
, otherwise it gets substituted with the last git
command you ran.
Thx to @Mixologic for pointing out that by simply using -R
on git diff
, the cumbersome sed
command is no longer required.
Linux Shell Script: backup and restore files while maintaining directory location
Consider using tar
: it remembers everything about the files, including paths, permissions, and dates. If you source code is inside a few directories, you can extract those directiories by name from the tar file.
Retaining file permissions with Git
The git-cache-meta
mentioned in SO question "git - how to recover the file permissions git thinks the file should be?" (and the git FAQ) is the more staightforward approach.
The idea is to store in a .git_cache_meta
file the permissions of the files and directories.
It is a separate file not versioned directly in the Git repo.
That is why the usage for it is:
$ git bundle create mybundle.bdl master; git-cache-meta --store
$ scp mybundle.bdl .git_cache_meta machine2:
#then on machine2:
$ git init; git pull mybundle.bdl master; git-cache-meta --apply
So you:
- bundle your repo and save the associated file permissions.
- copy those two files on the remote server
- restore the repo there, and apply the permission
Script to backup and restore an Informix database
After some discussion in comments and amendments to the question, the problem appears to be primarily in the 'recover' stage, and it may be that the trouble is with creating enough space in the dbspace.
I'm going to mention here that I find DB-Access distressing to use. So distressing that I wrote a program now called sqlcmd
to work the way I wish DB-Access did. Consider using SQLCMD (available from the IIUG Software
Archive), which
I wrote to behave consistently in shell scripting contexts whereas
DB-Access doesn't.
It dates back to 1986 (before there was dbaccess
; in those days, you
used isql
instead — DB-Access was carved out of isql
in an
evening) and was originally called rdsql
.
It bears no relation to Microsoft's johnny-come-lately program of the
same name — except for the name and having the same general purpose
(manipulate SQL databases).
I mention it because scripting for "is there already a dbspace called 'xyz'?" becomes trivial:
dbspace="xyz"
if [ -n "$(sqlcmd -d sysmaster "select name from sysdbspaces where name = '$dbspace'") ]
then : dbspace exists - add space to it
else : dbspace does not exist - create it
fi
With DB-Access, this is harder. What should work is something along the lines of:
dbspace="xyz"
result=$(dbaccess sysmaster - 2>/dev/null <<EOF
select name from sysdbspaces where name = '$dbspace';
EOF
)
if [ -n "$result" ]
then : dbspace exists - add space to it
else : dbspace does not exist - create it
fi
This code should be encapsulated into a shell function or a shell script called dbspace_exists
that can be used by scripts. It should return 0 or exit with status 0 if the dbspace exists; it should return a non-zero value or exit with a non-zero status if the dbspace does not exist. (And it shouldn't generate any output by default!) I'd use a script because the performance impact is negligible and the clarity and reusability is much simpler. YMMV!
Chunk files must exist and have appropriate permissions before running onspaces
. The following works if the user running the script is root
or has system administrator privileges. Drop thechown
line if necessary, but note that if the owner is not user informix, group informix, the new chunk path may not work at all.
cp /dev/null "$chunkpath"
chown informix:informix "$chunkpath"
chmod 660 "$chunkpath"
Your code keeps repeating some constructs — use variables so you stay DRY ("Don't Repeat Yourself").
You have something along the lines of:
cd $DBSTOR # Changed from DBPATH
tar -xzvf $ARCHIVE
onspaces -c -d dbs_"$BASE"_01 -p /bases_data/data_"$BASE"_01.dbs -o 0 -s ${size_dbs2}
dbimport -q "$BASE" -d dbs_"$BASE"_01
echo "Import done"
I think you need something more like:
cd "${DBSTOR}" || exit 1
tar -xzvf "${ARCHIVE}"
dbspace_name="dbs_${BASE}_01"
dbspace_path="/bases_data/${dbspace_name}.dbs"
if [ -f "$dbspace_path" ]
then
echo "$0: dbspace chunk file $dbspace_path already exists" >&2
exit 1
fi
cp /dev/null "$dbspace_path"
chown informix:informix "$dbspace_path"
chmod 660 "$dbspace_path"
if dbspace_exists "$dbspace_name"
then onspaces -a "$dbspace_name" -p "$dbspace_path" -o 0 -s "${size_dbs2}"
else onspaces -c -d "$dbspace_name" -p "$dbspace_path" -o 0 -s "${size_dbs2}"
fi
if [ "$?" != 0 ]
then
echo "$0: failed to create/expand dbspace $dbspace_name" >&2
exit 1
fi
if dbimport -q "$BASE" -d "$dbspace_name"
then echo "Import of $BASE done"
else
echo "Import of $BASE failed" >&2
exit 1
fi
# Remove the files extracted from the tar file
rm -fr …
exit 0
You should do an archive before trying to use the new dbspace — I've not integrated that into the script. Without the archive, the extra chunk may not be available.
There is still a lot of polishing to do.
Note the use of the braces in dbspace_name="dbs_${BASE}_01"
. This ensures that the variable name is ${BASE}
and not $BASE_01
. Your circumvention is effective but clumsy and not idiomatic shell. I usually quote variables, and often embed the variable names in braces `"${dbspace_name}". If you don't have spaces or strings touching the variable name, you can do without the extra punctuation, but it helps in the long run.
Related Topics
How to Replace Just One Newline Between > and < in Unix
How to Base64 Encode Image in Linux Bash/Shell
X11/Xlib.H Not Found in Ubuntu
New to Linux Kernel/Driver Development
How to Skip Saturday and Sunday in a Cron Expression
Bashrc Not Loading Until Run Bash Command
"Git Add" Returning "Fatal: Outside Repository" Error
Checking for Installed Packages and If Not Found Install
When a Parent Process Is Killed by "Kill -9", Will Subprocess Also Be Killed
Find and Remove a Line in Multiple Files
Colored Shell Script Output Library
Best Practices for Git Repositories on Open Source Projects
How to Set the Grep After Context to Be "Until the Next Blank Line"
How I Should Run My Golang Process in Background
How to Give a Linux User Sudo Access
Should I Put Trailing Slash After Source and Destination When Copy Folders