当前位置: 首页 > 知识库问答 >
问题:

从远程ssh服务器上的tar存档中提取某些文件

郭俊人
2023-03-14

我正在远程服务器上运行大量模拟(通过ssh)。这些模拟的结果作为.tar存档存储在此远程服务器上的存档目录中。

我想做的是编写一个bash脚本,它通过ssh连接到远程服务器,并从每个服务器中提取所需的输出文件。tar存档到本地硬盘上的单独文件夹中。

这些文件夹应与文件来自的.tar文件同名(例如,假设模拟 1 的输出存储在存档 S1 中.tar远程服务器上的存档中,我希望 .tar将此存档中的所有“.dat”和“.def”文件提取到我的本地驱动器上的目录 S1)。

对于提取本身,我试图:

for f in *.tar; do
(
    mkdir ../${f%.tar}
    tar -x -f "$f" -C ../${f%.tar} "*.dat" "*.def"
)
done
wait

每一个。tar文件大约有1GB,并且有很多。所以下载所有东西需要太多时间,这就是为什么我只想提取必要的文件(见上面代码中的扩展)。

现在,当我在本地驱动器上拥有.tar文件时,代码可以完美地工作。但是,我无法弄清楚的是,如果不首先从服务器下载所有.tar存档,我该怎么做。

当我第一次通过<code>ssh连接到远程服务器时username@host,然后终端停止使用脚本,只连接到服务器。

顺便说一句,我正在VS Code中执行此操作,并通过我的MacBook上的终端运行脚本。

我希望我已经描述得够清楚了。谢谢你的帮助!

共有1个答案

郭阳曜
2023-03-14

要获取要从检索的数据,请执行以下操作。对于tar文件,您需要使用--to-command选项将tar的结果传递给一个命令串。在下面的示例中,我们将运行三个命令。

# Send the files name back to your shell
echo $TAR_FILENAME

# Send the contents of the file back
cat /dev/stdin

# Send EOF (Ctrl+d) back (note: since we're already in a $'' we don't use the $ again)
echo '\004'

一旦在您的shell中捕获了信息,我们就可以开始处理数据了。这是一个分三步走的过程。

    < li >获取文件的名称 < ul > < li >注意,在这段代码中,我们根本不处理目录(只是将它们剥离;即< code>dir/1.dat -
# Get the files via ssh and tar
files=$(ssh -n <user@server> $'tar -xf <tar-file> --wildcards \'*\' --to-command=$\'echo $TAR_FILENAME; cat /dev/stdin; echo \'\004\'\'')

# Keeps track of what state we're in (filename or content)
state="filename"
filename=""

# Each line is one of these:
#  - file's name
#  - file's data
#  - EOF
while read line; do
  if [[ $state == "filename" ]]; then
    filename=${line/*\//}
    touch $filename
    echo "Copying: $filename"
    state="content"
  elif [[ $state == "content" ]]; then
    # look for EOF (ctrl+d)
    if [[ $line == $'\004' ]]; then
      filename=""
      state="filename"
    else
      # append data to file
      echo $line >> <output-folder>/$filename
    fi
  fi
# Double quotes here are very important
done < <(echo -e "$files")

如果上面的示例看起来对它正在做的事情过于复杂,那么它就是。一种更多地接触磁盘并需要单独的ssh连接的替代方法是将您需要的文件从. tar文件中提取到一个文件夹中,然后将scp该文件夹返回到您的工作站。

ssh -n <username>@<server> 'mkdir output/; tar -C output/ -xf <tar-file> --wildcards *.dat *.def'
scp -r <username>@<server>:output/ ./

首先,我们将腾出一个地方来保存输出的文件。如果您已经知道它们将位于的文件夹中,则可以跳过此步骤。

mkdir output/

然后,我们将匹配的文件提取到我们创建的此文件夹中(如果您不希望它们位于其他文件夹中,请删除 -C output/ 选项)。

tar -C output/ -xf <tar-file> --wildcards *.dat *.def

最后,现在我们再次在计算机上运行命令,我们可以运行 scp 来重新连接到远程计算机并将文件拉回。

scp -r <username>@<server>:output/ ./
 类似资料:
  • 问题内容: 给定 档案的网址(例如zip文件) 该归档文件中文件的全名(包括路径) 我正在寻找一种创建该文件的本地副本的方法(最好使用Java), 而无需先下载整个档案 。 根据我(有限的)理解,这应该是可能的,尽管我不知道该怎么做。我一直在使用TrueZip,因为它似乎支持各种各样的档案类型,但是我对其使用这种方式的能力感到怀疑。有人对这种事情有经验吗? 编辑: 能够同时使用tarball和压缩

  • 我试图使用spring-boot Application.properties连接到远程计算机上的MySQL server,但失败了,错误。

  • 问题内容: 我有一个包含要使用tar存档的文件列表的文件。叫它吧 它包含了: 有没有一种方法可以发出作为输入的TAR命令?就像是 这样就好像我发出以下命令一样: 问题答案: 是:

  • 我创建了一个Amazon Linux 2实例,在其中部署了一个用systemd启动的Java程序。Java程序是一个Vertex shell应用程序,它使用Apache Mina在端口2000上启动SSH服务器。应该可以通过两种方式连接到SSH服务器:公钥或密码验证。 在端口22上进行经典ssh身份验证以访问我的amazon实例后,我可以使用密码auth本地连接到在端口2000上运行的java s

  • 问题内容: 我们将Jenkins服务器用于日常构建过程,并通过SSH在远程主机上执行一些bash脚本。该脚本在远程主机上生成html日志文件。 我们正在使用“ 复制到从属”插件来复制从属计算机上的文件,并使用“ 通过ssh插件进行发布”来管理构建过程中的SSH会话。 现在的问题是,我们要将一些文件(脚本的日志文件)从远程ssh主机复制到Jenkins服务器。这将是可能的并且是相同的更好的选择(如果

  • 问题内容: 我试图通过这样的本地服务器上的ssh命令在远程linux服务器上执行命令: ssh myremoteserver’类型ttisql’ 其中ttisql是我的远程计算机路径上的可执行文件。 运行此命令的结果是: bash:第0行:类型:ttisql:未找到 当我只是先连接并执行以下操作: ssh myremoteserver 然后输入命令: [myuser @ myremoteserve