lftp:如何递归设置权限;首先按目录而不是按文件

lftp:如何递归设置权限;首先按目录而不是按文件,ftp,file-permissions,shared-hosting,batch-processing,lftp,Ftp,File Permissions,Shared Hosting,Batch Processing,Lftp,在不公开SSH访问的共享主机上保护Drupal或WordPress安装时(糟糕的情况,fwiw),lftp似乎是批量设置目录和文件权限的正确方法。find命令夸耀您可以重定向其输出,因此您应该能够运行find、grep exclude,以仅匹配以“/”结尾的行(表示目录),然后将此类匹配的权限设置为755,对文件匹配执行反向操作,并将其设置为644,然后微调特定文件,例如settings.php等等 lftp prompt> find . | grep "/$" | xargs chmod

在不公开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服务器权限更改,而不是本地perms更改。

有关此操作无法按预期工作的原因的解释,请继续阅读-有关给定问题的解决方案,请向下滚动

答案可在
lftp
的手册页中找到,其中说明

ome命令允许将其输出(cat、ls等)重定向到文件或通过管道重定向到外部命令

因此,当您在支持在
lftp
中重定向的命令上使用这样的管道时,您正在将其输出管道化到本地工具,这最终将导致
chmod
尝试更改本地计算机上文件/目录的权限,如果您在本地当前目录中没有相同的目录布局,则很可能会失败—这可能就是您遇到的问题

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

不是等价的。 是的,
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}"
#/bin/bash
server=“ftp.foo.bar”
root_folder=“/my/path”
{
{

lftp“${server}”不,lftp手册页引用是一种解释,但不是答案。问题仍然没有答案。我编写的命令的行为与您的猜测不符,fwiw。也没有错误输出。因此,提供一些粒度可能会有所帮助?我将相应地更新我的主要问题。@Kyle感谢您的更新!不,您理解吗对正在发生的事情的描述是不正确的(根据手册页引用)我更新了我的答案来说明原因。@Kyle好吧,你不可能在一次尝试中就完成,但可以使用你最初的find/grep管道作为基础编写脚本,请参阅我的更新答案。这很好。我目前没有一个网站可以对其进行全面测试,但基于我的飞行前检查,(根据你的建议)这非常适合我所寻找的。我仍然会请求我的客户端允许ssh连接,并将其用于顽固的连接。一些注释:lftp允许您定义书签,其作用类似于别名。因此,在准备过程中,您可以为相关服务器定义别名,然后将其传递到$server shell变量中。时间允许时,我将扩展它,以便将其作为arg传递到脚本中。顺便说一句,将文件设置为644真是太棒了。@Kyle Perfect!关于书签功能的好提示,请稍后查看,以防这给您带来任何头痛,因为我自己只做了一个快速测试:-)
#!/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}"