我试图用读写的文件描述在bash这样我就可以删除的文件,该文件描述,称之后,作为这样的:

F=$(mktemp)
exec 3<> "$F"
rm -f "$F"

echo "Hello world" >&3
cat <&3

cat 命令没有给出的输出。我能实现我想要什么,如果我使用单独的文件中描述符的阅读和写作:

F=$(mktemp)
exec 3> "$F"
exec 4< "$F"
rm -f "$F"

echo "Hello world" >&3
cat <&4

这指纹 Hello world.

我怀疑砸不会自动寻求开始的文件描述当你开关从文字来阅读,下列组合的庆典和代码证实了这一点:

fdrw.sh

exec 3<> tmp
rm tmp

echo "Hello world" >&3
exec python fdrw.py

fdrw.py

import os  

f = os.fdopen(3)
print f.tell()
print f.read()

它提供了:

$ bash fdrw.sh
12

$ # This is the prompt reappearing

有没有办法实现我想要的只是用来砸?

有帮助吗?

解决方案

没有。 bash中没有“求”,其重定向任何概念。它从开始到结束在一个长流中读取/写入(大部分)。

其他提示

如果你曾经碰巧想寻求的bash文件描述符,你可以使用一个子进程,因为它继承了父进程的文件描述符。下面是一个例子C程序来做到这一点。

seekfd.c

#define _FILE_OFFSET_BITS 64
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    /* Arguments: fd [offset [whence]]
     * where
     * fd: file descriptor to seek
     * offset: number of bytes from position specified in whence
     * whence: one of
     *  SEEK_SET (==0): from start of file
     *  SEEK_CUR (==1): from current position
     *  SEEK_END (==2): from end of file
     */
    int fd;
    long long scan_offset = 0;
    off_t offset = 0;
    int whence = SEEK_SET;
    int errsv; int rv;
    if (argc == 1) {
        fprintf(stderr, "usage: seekfd fd [offset [whence]]\n");
        exit(1);
    }
    if (argc >= 2) {
        if (sscanf(argv[1], "%d", &fd) == EOF) {
            errsv = errno;
            fprintf(stderr, "%s: %s\n", argv[0], strerror(errsv));
            exit(1);
        }
    }
    if (argc >= 3) {
        rv = sscanf(argv[2], "%lld", &scan_offset);
        if (rv == EOF) {
            errsv = errno;
            fprintf(stderr, "%s: %s\n", argv[0], strerror(errsv));
            exit(1);
        }
        offset = (off_t) scan_offset;
    }
    if (argc >= 4) {
        if (sscanf(argv[3], "%d", &whence) == EOF) {
            errsv = errno;
            fprintf(stderr, "%s: %s\n", argv[0], strerror(errsv));
            exit(1);
        }
    }

    if (lseek(fd, offset, whence) == (off_t) -1) {
        errsv = errno;
        fprintf(stderr, "%s: %s\n", argv[0], strerror(errsv));
        exit(2);
    }

    return 0;
}

我发现一个方法做到这一庆典,但它依靠一个不起眼的功能 exec < /dev/stdin 这实际上可以倒退的文件描述的根据stdin http://linux-ip.net/misc/madlug/shell-tips/tip-1.txt:

F=$(mktemp)
exec 3<> "$F"
rm -f "$F"

echo "Hello world" >&3
{ exec < /dev/stdin; cat; } <&3

写的描述符并不是受到影响,所以你仍然可以将输出追加以描述前3猫。

可悲的是我只有这个工作在Linux不下mac os(BSD),即使有的庆典的最新版本。因此,它不似乎非常便于携带。

尝试改变的命令的序列:

F=$(mktemp tmp.XXXXXX)
exec 3<> "$F"
echo "Hello world" > "$F"
rm -f "$F"

#echo "Hello world" >&3
cat <&3

当你在这样的庆典打开一个文件描述符,它成为在/dev/fd/文件访问。 在那你可以做cat,它会从一开始,或追加(echo "something" >> /dev/fd/3)读取,它会把它添加到末尾。 至少在我的系统上它的行为这种方式。 (在另一方面,我似乎无法能够得到“猫<&3”的工作,即使我没有做任何书面的描述)。

#!/bin/bash
F=$(mktemp tmp.XXXXXX)
exec 3<> $F
rm $F

echo "Hello world" >&3
cat /dev/fd/3

正如在其他答案建议cat会倒带你的文件描述符从中读取之前,因为它认为它只是一个普通的文件。

要“倒带”文件描述符,可以简单地使用/proc/self/fd/3

测试脚本:

#!/bin/bash

# Fill data
FILE=test
date +%FT%T >$FILE

# Open the file descriptor and delete the file
exec 5<>$FILE
rm -rf $FILE

# Check state of the file
# should return an error as the file has been deleted
file $FILE

# Check that you still can do multiple reads or additions
for i in {0..5}; do
    echo ----- $i -----

    echo . >>/proc/self/fd/5
    cat /proc/self/fd/5

    echo
    sleep 1
done

尝试杀死-9脚本在运行时,你会看到相反的是有陷阱的方法发生,文件实际删除。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top