当在不公开SSH访问的共享主机上保护Drupal或WordPress安装时(糟糕的情况,fwiw),lftp似乎是批量设置目录和文件权限的正确方法。find命令声称您可以重定向其输出,因此应该能够运行find,grep-exclude,只匹配以"/"结尾的行,即目录,然后将这些匹配的权限设置为755,对文件匹配执行相反的操作并设置为644,然后微调特定文件,如settings.php等。
lftp prompt> find . | grep "/$" | xargs chmod -v 755
不起作用,我确信我未能按正确的顺序和格式链接这些命令。
如何让它发挥作用?
更新:通过"不工作",我的意思是上面的命令不会向控制台输出,也不会向lftp错误日志输出。它不是在本地运行这些命令,fwiw。我将减少命令作为演示:
find . | grep "/$"
将获取"find"的输出并返回匹配项,此处为目录,按字符串的性质匹配:
./daily/
./ffmpeg-installer/
./hourly/
./includes/
./includes/database/
./includes/database/mysql/
./and_so_forth_on_down
这很酷,因为我希望执行chmod(以及lftp的内部命令,支持程度因ftp服务器而异),所以我扩展命令如下:
find . | grep "/$" | xargs echo
它什么也没输出。也没有错误输出。从grep到xargs的管道没有发生。
我的目标是形成相当于:
chmod 755 ./daily/
chmod 755 ./ffmpeg-installer/
在lftp中,chmod命令正在执行ftp服务器权限更改,而不是本地权限更改。
要解释为什么这不能按预期工作,请继续阅读-要找到给定问题的解决方案,请向下滚动。
答案可以在lftp
的手册页中找到,其中指出
"[s]ome命令允许将其输出(cat、ls、…)重定向到文件或通过管道重定向到外部命令。">
因此,当您在lftp
中支持重定向的命令上使用这样的管道时,您将其输出管道传输到您的本地工具,这最终将导致chmod
尝试更改我们的local机器上的文件/目录的权限,如果您在本地当前目录中没有相同的目录布局,则很可能会失败——这可能是您遇到的问题。
grep
+xargs
管道确实工作,我刚刚测试了以下内容:
lftp> find -d 2 | grep "/$"
./
./applications/
./lost+found/
./netinfo/
./packages/
./security/
./systems/
lftp> find -d 2 | grep "/$" | xargs echo
./ ./applications/ ./lost+found/ ./netinfo/ ./packages/ ./security/ ./systems/
我的猜测是,它似乎对你不起作用,因为你没有指定要查找的最大深度,而且网络连接+管道中的缓冲阻碍了你。当我在包含许多文件/子文件夹的目录上尝试同样的操作时,完成和打印需要很长时间。命令真的在没有输出的情况下为您完成了吗?
但是,你想做的仍然是不可能的。正如我所说,管道的右侧与外部命令一起工作(即使存在相同名称的内置命令),如手册所述,因此
lftp> chmod 644 foobar
和
lftp> echo "foobar" | xargs chmod 644
是而不是等效。是的,chmod
是一个内置的,但在客户端的管道中使用,它将而不是执行内置-手册页明确说明了这一点,您可以自己轻松测试。尝试以下命令并检查其输出:
lftp> echo foo | uname -a
lftp> echo foo | ls -al
lftp> echo foo | chmod --help
lftp> chmod --help
解决方案
就你的问题的解决方案而言,你可以尝试以下方法:
#!/bin/bash
server="ftp.foo.bar"
root_folder="/my/path"
{
{
lftp "${server}" <<EOF
cd "${root_folder}"
find | grep "/$"
quit
EOF
} | awk '{ printf "chmod 755 "%s"n", $0 }'
{
lftp "${server}" <<EOF
cd "${root_folder}"
find | grep -v "/$"
quit
EOF
} | awk '{ printf "chmod 644 "%s"n", $0 }'
} | lftp "${server}"
这将登录到您的服务器,cd
s到您要递归开始更改权限的文件夹,使用find + grep
查找所有目录,注销,将此文件列表管道传输到awk
中以围绕它构建chmod
命令,对文件重复整个过程,然后将整个命令列表管道传输至新的lftp
调用中,以实际运行生成的chmod
命令。
您还必须将凭据添加到lftp
调用中,并且可能需要注释掉最终的| lftp "${server}"
,以在实际运行整个过程之前检查它是否产生了所需的输出。如果这对你有用,请反馈!