例如我有目錄
/path/to/directory
我想將其子目錄的權限設定為某些內容。這很容易:
find /path/to/directory -type d -exec chmod something {} +
但我該如何反向操作?我需要設定相同的權限
/path
並
/path/to
並
/path/to/directory
我有很多這樣的目錄,我正在尋找一些腳本解決方案
答案1
向上遞歸直到/
到達並為每個目錄呼叫函數。
#!/bin/sh
function mangleperms {
echo DEBUG would chmod 755 "$1"
}
function walktoroot {
DIR="$1"
HANDLE="$2"
if [ "$DIR" = "/" ]; then
return
fi
"$HANDLE" "$DIR"
# recursion (noun): see recursion
PARENTDIR=`dirname "$DIR"`
walktoroot "$PARENTDIR" "$HANDLE"
}
if [ -z "$1" ]; then
echo >&2 "Usage: walktoroot dir"
exit 1
fi
# TODO probably more edge cases on relative dirs, though there are means
# to fully qualify those
if [ "$1" = "." ]; then
DIR=`pwd`
else
DIR=$1
fi
walktoroot "$DIR" mangleperms
例如
$ pwd
/var/tmp/a/b/c
$ /home/jdoe/walktoroot .
DEBUG would chmod 755 /var/tmp/a/b/c
DEBUG would chmod 755 /var/tmp/a/b
DEBUG would chmod 755 /var/tmp/a
DEBUG would chmod 755 /var/tmp
DEBUG would chmod 755 /var
$
答案2
我們find
可以這樣做:
find /path/to/dir -type d -prune -exec chmod 755 {} \; -exec sh -c '
while { set -- "${1%/*}"; case $1 in "" ) break ;; esac; }
do find "$1" -type d -prune -exec chmod 755 \{\} \;; done
' {} {} \;
另一種使用函數的方法recursive
:
fx() {
case $1 in ?* ) chmod 755 "$1"; fx "${1%/*}" ;; esac
}
# and then...
fx /path/to/dir
答案3
嗯,路徑只是一個字串。因此,您可以將其拆分/
並將命令應用於每個結果。例如,您可以使用一點 Perl 單行程式碼來列印出父路徑:
$ path=/path/to/some/deeply/buried/thing
$ echo "$path" | perl -F"/" -lane 'for(1..$#F){print join("/",@F[0..$_])}'
/path
/path/to
/path/to/some
/path/to/some/deeply
/path/to/some/deeply/buried
/path/to/some/deeply/buried/thing
如果您現在使用該 perl 命令建立函數(執行此命令或將其新增至 shell 的初始化檔案 —~/.bashrc
如果您使用的是bash
):
pexpand(){
printf '%s\n' "$1" | perl -F"/" -lane 'for(1..$#F){print join("/",@F[0..$_])}';
}
現在,您可以像這樣使用它:
$ pexpand $path
/path
/path/to
/path/to/some
/path/to/some/deeply
/path/to/some/deeply/buried
/path/to/some/deeply/buried/thing
您可以使用以下命令在該路徑中的每個目錄上執行命令:
chmod 733 "$(pexpand "$path")"
如果您的路徑可以包含換行符,上述方法將會失敗。更強大的版本是:
pexpand(){
perl -le '@F=split(/\//, $ARGV[0]);
for(1..$#F){printf "%s\0",join("/",@F[0..$_])}' "$1";
}
不過使用起來比較麻煩:
pexpand "$path" | while IFS= read -r -d '' d; do chmod 733 "$d"; done
因此,如果您需要它處理任意輸入,我建議編寫一個小腳本,將路徑和命令作為輸入:
#!/usr/bin/perl
my $comm = $ARGV[0] || die "At least 2 arguments are necessary\n";
my $path = $ARGV[1] || die "At least 2 arguments are necessary\n";
my @paths=split(/\//, $path);
for (1..$#paths) {
system("$comm \"" . join("/",@paths[0..$_]) . "\"");
}
將該腳本另存為foo.pl
目錄中的某個內容(或其他內容)$PATH
,使其可執行(chmod a+x ~/bin/foo.pl
),然後您現在可以像這樣運行它:
foo.pl "chmod 700" /path/to/some/deeply/buried/thing