Unix 在Solaris上查找和tar文件
我的bash脚本有点问题。我是unix世界的新手,所以我发现很难进行练习。我要做的是在Solaris服务器上查找具有特定名称、在特定时间修改的文件,并将它们归档到一个.tar文件中。前两点很简单,但我正在做一个噩梦,试图将其归档。问题是,我不断地将整个文件树(末尾是file)归档到.tar文件,但我只需要一个文件。我的代码如下所示:Unix 在Solaris上查找和tar文件,unix,find,solaris,tar,Unix,Find,Solaris,Tar,我的bash脚本有点问题。我是unix世界的新手,所以我发现很难进行练习。我要做的是在Solaris服务器上查找具有特定名称、在特定时间修改的文件,并将它们归档到一个.tar文件中。前两点很简单,但我正在做一个噩梦,试图将其归档。问题是,我不断地将整个文件树(末尾是file)归档到.tar文件,但我只需要一个文件。我的代码如下所示: find ~ -name "$maska" -mtime -$dni | xargs -t -L 1 tar -cvf $3 -C #!/bin/bash fin
find ~ -name "$maska" -mtime -$dni | xargs -t -L 1 tar -cvf $3 -C
#!/bin/bash
find ~ -name "$maska" -mtime -$dni -print0 | while read -d $'\0' file; do
d=$(dirname "$file")
f=$(basename "$file")
echo $d: $f # Show directory and file for debug purposes
tar -rvf tarball.tar -C"$d" "$f"
done
其中,$maska是文件名,$dni表示修改时间,$3只是归档文件名。我发现关于-C开关,让我跳转到所需文件所在的文件夹中,但当我将其与xargs一起使用时,它似乎只是跳转到那里,而不做任何其他事情
所以我的问题是:
1) 有没有可能通过这种方式实现我的目标
请记住,我不在gnu焦油上工作。我必须使用命令:tar,find
编辑:我想详细说明我的问题。例如,当我为文件a使用脚本时,它应该查找它,因为脚本中显示的点(它是~)和它将找到的所有内容都应该在一个tar文件中
我现在得到的是(我在/home/me/Scripts中):
所以脚本做了一些打包。接下来,我想查看我的打包文件,因此:
-bash-3.2$ tar -tf backup
/home/me/Program/Test/a/
/home/me/Program/Test/a/a.c
/home/me/Program/Test/a/a.out
这就是问题所在。Tar文件中有所有的路径,所以如果我要取消Tar,而不是只获取我想要归档的文件,我会将它们替换到原来的位置。对于可视化:
-bash-3.2$ ls
Script.sh* Script.sh~* backup
-bash-3.2$ tar -xvf backup
x /home/me/Program/Test/a, 0 bytes, 0 tape blocks
x /home/me/Program/Test/a/a.c, 39 bytes, 1 tape blocks
x /home/me/Program/Test/a/a.out, 7928 bytes, 16 tape blocks
-bash-3.2$ ls
Script.sh* Script.sh~* backup
这就是问题所在
因此,我只想将所有需要的文件(上面示例中的a)打包到一个tar文件中,而不使用这些路径,这样就可以在我运行Script.sh的目录中解压。我不确定您想要什么,但这可能是:
find ~ -name "$maska" -mtime -$dni -exec tar cvf $3 {} +
编辑:在写入后第二次尝试,主要问题是绝对路径:
( cd ~; find . -name "$maska" -type f -mtime -$dni -exec tar cvf $3 {} + )
编辑:第三次尝试,在您编写完您根本不想在存档中使用任何路径后,maska
是一个目录名,$3
需要位于当前目录中:
mkdir ~/foo && \
find ~ -name "$maska" -type d -mtime -$dni -exec sh -c 'ln -s $1/* ~/foo/' sh {} \; && \
( cd ~/foo ; tar chf - * ) > $3 && \
rm -rf ~/foo
如果由于某种原因,
~/foo
已经存在,则将~/foo
替换为~/somethingElse
。也许您可以这样做:
find ~ -name "$maska" -mtime -$dni | xargs -t -L 1 tar -cvf $3 -C
#!/bin/bash
find ~ -name "$maska" -mtime -$dni -print0 | while read -d $'\0' file; do
d=$(dirname "$file")
f=$(basename "$file")
echo $d: $f # Show directory and file for debug purposes
tar -rvf tarball.tar -C"$d" "$f"
done
我手头没有用于测试的Solaris设备:-)首先,我的假设: 1.“一个tar文件”,就像你说的,还有 2.没有绝对路径,即如果备份~/dir/file,应该能够在/tmp/tmp/dir/file中测试提取它 如果问题是完整路径,则应替换
find ~ # etc
与
如果tar归档不是一个绝对名称,那么它应该是
(
cd ~ || exit
find . etc etc | xargs tar cf - etc etc
) > $3
解释
“(…)”运行一个子shell,这意味着你在其中更改的某些内容在parens之外没有任何影响;当前目录就是其中之一,因此“(cd whatever;foo)”意味着您运行另一个shell,更改其当前目录,从那里运行foo,然后您回到从未更改过目录的脚本中
“cd~ | |退出”是偏执狂,意思是“cd~;如果失败,退出”
“.”是一个别名,意思是“当前目录,无论它是什么”;玩“find.”vs“find~”如果你不知道它的意思,你会比我在这里解释的更好理解它
“tar cf-”表示您在标准输出上创建tar归档;我认为该语法具有足够的可移植性,您可能必须将“-”替换为“/dev/stdout”或在solaris上工作的任何东西(最简单的解决方案是简单的“tar”,没有“c”命令,但读起来很难看)
在parens之外的最后一个“>$3”是输出重定向:不是将输出写入终端,而是将其保存到文件中
因此,整个脚本如下所示:
-打开子shell
-将子shell的当前目录更改为~
-在子shell中,找到比请求的文件更新的文件,将其归档,并将生成的tar归档的内容写入标准输出
-子shell的标准存储为3美元;因为重定向在parens之外,所以相对路径相对于脚本的$PWD进行解析,这意味着,例如,如果从/tmp目录运行脚本,则会在/tmp目录中获得tar存档(如果重定向发生在子shell中,则会在~中)
如果我误解了您的问题,解决方案不起作用或解释不清楚,请告诉我(答案太长,但我已经知道:)。将输出与tar兼容的存档,并具有重写路径名所需的灵活性
find ~ -name "$maska" -mtime -$dni | pax -w -x ustar -f "$3" -s '!.*/!!'
以下是这些选项的含义,从手册页中转述:
- -
以存档格式将文件操作数的内容写入标准输出(或写入w
选项指定的路径名)-f
输出存档格式是IEEE POSIX标准中指定的扩展-x ustar
交换格式tar
-s'!.*/代码>使用正则表达式语法,根据替换表达式修改文件操作数。在这里,它删除每个文件名中从开头到结尾的所有字符
~/tmp
,以免干扰我自己的文件。我会删除的。是的,还是没有回应。我想它应该只是创造