【问题标题】:How delete file from fortran code?如何从 fortran 代码中删除文件?
【发布时间】:2013-09-11 04:57:31
【问题描述】:

我需要从Fortran 代码中删除一个文件。我在ubuntu 12.04, x86_64。我不明白为什么下面描述的过程不起作用。请帮助我澄清情况(实际上,在某些系统上,它有效,但不适用于我的)。

还有一种方法:我可以直接调用unix命令rm -f file,但是我想知道我的方法有什么问题。谢谢。

步骤1.制作简单的脚本del.sh并放入~/bin

$ cat del.sh
[ $# -ge 1 ] && rm -f $1
$ chmod u+x del.sh; mv del.sh ~/bin 

步骤 2. Fortran 代码,del.for:

character*100 cmd
character*30 file
call getarg(1,file)
write(cmd,100) file
100   format('source del.sh ',a30)
call system(cmd)
end

步骤 3. 编译并运行:

$ ifort -o del del.for
$ ./del file

结果:

sh: 1: source: not found

怎么了?简单的“源 del.sh 文件”有效,但不是来自 Fortran 代码……这令人困惑。

来自 Fortran 代码:

100 format('del.sh ',a30)
100 format('bash del.sh ',a30)

工作完美,但是

100 format('sh del.sh ',a30)

不起作用。我安装了bash,但没有安装csh。谢谢。

【问题讨论】:

  • 你知道一个文件也可以通过以'SCRATCH'状态打开然后关闭它来删除。这可以在所有操作系统中移植,无需弄乱脚本或操作系统命令用于删除文件。
  • cup 和@AlexanderVogt:谢谢你的回答。是的,Fortran 可以删除文件,我知道。从 Fortran 代码调用脚本的想法应该使您的程序更加灵活:脚本可以根据您的需要轻松修改和调整,而无需重新编译项目。例如,我可以备份它而不是删除文件等等。我的另一个问题是:为什么所描述的方法不起作用?我只是好奇...
  • 旧的 f77 标准实际上只是简单地说“不能用命名文件指定 SCRATCH”。我不知道以这种方式删除命名文件的便携性如何?
  • @george:好点子。猜猜最好的选择是按照 AlexanderVogt 的建议以旧状态打开并以删除状态关闭。
  • @axion:如果您在脚本顶部添加 #!/bin/sh 是否有效? /bin/sh 存在吗?

标签: linux bash file shell fortran


【解决方案1】:

所以在你的 shell 脚本中,你没有在第一行指定程序。尝试添加:

#!/bin/bash

作为 del.sh 的第一行。当 bash 在没有它的情况下启动它时,它可能正在运行带有 /bin/sh 的脚本,而不是您期望的 /bin/bash。 (我现在无法确认,但我知道如果我使用特定于 bash 的代码但忘记将 shebang 放在顶部,我过去会遇到麻烦。)当 bash 以该行开头时,它将看到它需要用 bash 来执行。由于您的代码似乎表明直接将其作为 bash 参数调用是有效的,所以我认为这应该可以解决您的问题。 一切顺利。

【讨论】:

  • user2600110,谢谢你的回答。这就是我想要的 - 了解为什么它不能按预期工作。我尝试在脚本中添加相应的标题行(如您所述) - 它没有解决问题。
【解决方案2】:

source 是一个内置的 shell,它在当前进程中加载​​另一个脚本(而不是在子进程中运行它)。

正如您所发现的,当您从 Fortran 调用脚本时,您不需要 source。两个都 del.shbash del.sh 工作,其中任何一个都代表你应该这样做的方式。

【讨论】:

  • 谢谢你,吉姆。我相信这是迄今为止最好的答案。因此,通过源“将脚本加载到当前进程”是错误的意图/风格,这就是为什么它不起作用(或至少不应该起作用),对吗?当然,我想执行脚本,而不是加载它。有趣的是,它可以在其他机器上运行......请问Fortran和shell创建的进程有什么区别? (感谢您编辑我的问题)。
  • 没有区别,一个进程就是一个进程。它可能已经在其他机器上运行,可能是因为实现调用了一个 shell 来执行你的命令行,而不是直接运行它。没有更多细节很难说。
【解决方案3】:

为什么不让 Fortran 为您完成这项工作?这段代码是可移植的(比较cup的评论):

open(unit=1234, iostat=stat, file=file, status='old')
if (stat == 0) close(1234, status='delete')

【讨论】:

  • Alexander 和@cup,无论如何,我认为你们都提到的在 Fortran 中删除文件可能是一种更好的风格。谢谢。
  • 张贴的表格是一个很好的起点,但有一个问题,它会默默地忽略错误。
  • 我必须在序言中声明 INTEGER stat 吗?
  • @Machinato 是的,你应该
【解决方案4】:

system 调用调用 shell 来执行您的命令,该 shell 取决于系统/环境。因为你得到sh: 1: source: not found,所以被调用的shell 不理解source 命令,这是一个bash 内置命令。在 Ubuntu 上,默认情况下 /bin/sh 链接到 /bin/dash,而不是 /bin/bash,并且 dash 不理解 source。相反,使用.(便携式)内置而不是source

100   format('. del.sh ',a30)

如果del.sh 在您的$PATH 中,应该可以工作。

这就是为什么我认为这些都应该起作用:

100 format('sh del.sh ',a30)
100 format('bash del.sh ',a30)
100 format('del.sh ',a30)

但你有不同的看法?在那种情况下,打败我:)

【讨论】:

  • 有趣的是,. del.shsh del.shsource del.sh 版本不起作用,而 bash del.shdel.sh 工作正常。这可能只是因为我的配置。除了吉姆的回答,我不明白为什么会这样。但是您是对的,我们应该开始挖掘错误消息:sh: 1: source: not found。我尝试了许多变体,例如,如果del.sh$PATH 中,即使在命令行中sh del.sh 也不起作用,如果我将脚本保存在本地,那么sh 可以工作。谢谢!
  • 当你执行“sh script”时,sh 必须在你的路径上,但路径不是搜索脚本,它必须在当前目录中。我认为这里最安全的方法(假设 linux)是使用适当的 shebang 行 en.wikipedia.org/wiki/Shebang_%28Unix%29 使脚本可执行,然后直接执行脚本(不要 source ,不要调用另一个子 shell)(即最后一种 steaberts 方法)
  • @george:是的,那是我之间的误解:源,调用子 shell 并执行。此外,我相信在 Fortran 中使用system 命令调用时,任何从命令行(如source del.sh)工作的东西都必须工作。显然它可能会或可能不会起作用。我会检查 shebang 选项 - 谢谢。
【解决方案5】:

请尝试

call system(trim(cmd))

【讨论】:

  • 修剪不应在system 语句中造成任何差异。
猜你喜欢
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
相关资源
最近更新 更多