我能否将这些文件从报废的机器上拯救出来,避免被遗忘?

我能否将这些文件从报废的机器上拯救出来,避免被遗忘?

首先,我要坦白:不,我没有做应该做的备份。

二、情况:

我有一台戴尔 XPS 9550固态磁盘跑步Fedora 25

我正在处理一个文件并尝试保存它,这时系统提示我正在尝试保存到只读文件系统。事实证明我的文件系统现在是只读的,并且有输入/输出错误到处都是。

我能够通过打开的 Web 浏览器将一些文件通过电子邮件发送给自己,从而保存这些文件,但浏览器崩溃了,我无法重新启动它。但我仍然在编辑器中打开了一些感兴趣的文件。我似乎无法将文件保存到任何地方,但我可以复制它们的内容。如果我能找到一种方法来窃取文件内容,我就可以节省几个月的工作时间。

但是有一些可怕的限制。我尝试插入 USB 驱动器,但似乎没有设备代表它,并且命令mount因段错误而失败。我可以尝试 ssh 到另一台计算机,但出现“总线错误”并且它失败了。ping,,,dmesg这些ifconfig都不起作用。但我确实有vim并且less可以ls生成新bash实例。

lynx,不firefox,不google-chrome。没有 DVD 驱动器。

基本上,我的固态硬盘似乎坏了。或者可能是整个主板都坏了。我的内存中仍有一些非常有价值的文档,我有 IP 地址和网络连接,我可以运行一些随机命令,路径上还有 3500 多个命令可以尝试。

cat并且gcc似乎可以正常工作。我可以写入 /tmp 中的文件。我有一个正在运行的ipython实例,它似乎仍然可以工作。

所以……我到目前为止尝试过的方法都失败了。但我觉得仍有上千种可能性。我没考虑到什么?我怎么才能把这些文件从我快要坏掉的电脑里弄出来?

一定有办法的。

更新: 新的东西:

  • 由于我自己的愚蠢,我失去了网络连接。
  • 我编写了一个 Python 脚本来替换cpcp -r
  • 除非我找到某种方法来/dev为 SD 卡或 USB 驱动器创建条目,否则获取数据的最佳选择似乎是屏幕以及可能的扬声器/音频线。
  • 我正在编写一个脚本来尝试读取文件并输出哪些文件是可读的。

仍然非常欢迎提出建议!

更新2:较新内容:

  • 我在坏掉的电脑上写了一个 Python 脚本,它会逐位读取文件,并尝试通过在屏幕上闪烁一种或另一种颜色来传达这些位。现在它正在尝试执行一个两位代码,其中红色、绿色、蓝色和白色都代表一个两位对。不过,这种方法效果不太好,所以我可能会切换到两种颜色,一次执行一位。
  • 在我的另一台笔记本电脑(我为了这台热门的新款 XPS 放弃了那台值得信赖的旧款 Thinkpad)上,我编写了一个使用 OpenCV Python 库从网络摄像头读取数据的脚本。其目的是让它解码另一台计算机发送的代码。问题是摄像头的帧速率大约是每秒 15 帧,这意味着如果我的传输完美无误,我的最大数据速率将是每秒 30 位,即每秒 225 字节。即每天 324k。
  • 在即将报废的 XPS 上,我可以使用tar它将所需文件打包成一个 1.7 MB 的存档。不幸的是,、、gzip和任何压缩实用程序都不可用。但使用 Python 的模块,我可以将此文件压缩到 820KB。考虑到这个大小,我可能可以在几天内将其发送过来。bzip2xzlzopzlib
  • 由于这种传输方法很容易出错,所以我将在 XPS 上实现汉明码,以便在传输数据时添加一些错误修正。
  • 因为事情就是这样,所以可能会出现一些复杂情况,但至少获取这些数据似乎是可行的!
  • 由于这仍然是一种非常糟糕的数据发送方式,我进一步研究了 USB 串行驱动程序。我尝试加载的模块(usb-serial-simple、、)给出了 I/O 错误。我也不认为它内置在内核中,因为不存在 /dev/ttyUSB* 设备。usb-debugsafe-serial

感谢大家迄今为止提出的建议——我知道这甚至不是一个定义明确的问题,因为你们事先不知道哪些程序/文件可以读取,哪些不能读取。仍然愿意接受比这种视频方法更好的建议!

更新 3: 最新内容

  • 我买了一个 PS3 Eye 网络摄像头,在禁用自动增益和曝光后,我成功地从 XPS 读取了数据,尽管每秒读取 1 字节的数据时出错了。这是一个巨大的成功——第一批数据被泄露了!但读取速度太慢了,无法在任何合理的时间内读取 820KB 的数据,而且错误率太高了。

带时钟的一位传输

  • 问题是写入终端的速度太慢。屏幕更新并不是即时的,这(我认为)是由于urxvt我使用的终端仿真器速度太慢。
  • 我发现 XPS 上有一个 Rust 编译器。我用 Rust 重写了传输脚本,看看这是否能提高终端刷新速度,但没用。
  • 由于我不太可能提高帧速率,因此我必须尝试增加每帧获取的数据量。我目前的方法如下:

电网传输

右半部分仍然是时钟信号,闪烁以标记新帧的到来。但左半部分现在是一个网格,每个单元格角落都有一个红色方块标记,然后红色方块右下方的绿色单元格闪烁以指示一个位。红色方块应该让接收计算机校准单元格的位置。我还没有通过这种方式获得任何数据,但这就是我正在研究的。

  • 有人建议我研究编写二维码,而不是这些临时的彩色图案。我也打算研究一下,也许会实现它而不是这种网格方法。纠错将是一个不错的胜利,并且能够使用标准库进行解码。
  • 我了解到我可以访问 libasound(ALSA 声音库),但不能访问与其关联的头文件(alsa/asoundlib.h或其他文件)。如果有人知道如何使用没有头文件的共享库,或者可以帮助我编写正确的头文件以生成音频输出,那么我就可以通过音频方式获取文件。
  • 或者,如果有人可以帮助我在不访问 libusb 的情况下操作 USB 设备,那么我可以用它做些什么?

向前进!

更新 4:音频输出已产生!

用户 Francesco Noferi 做了一些很棒的工作,帮助我利用了上一次更新中提到的 ALSA 库。C 编译器有问题,但使用 Rust 编译器,我能够使用 FFI 直接调用libasound。我现在已经通过音频播放了大量数据,听起来就像音乐一样!仍然需要建立一个真正的通信渠道,但我感到非常有希望。目前我的工作基本上是实现调制解调器,所以如果有人对实现调制解调器的好方法有任何指导,我洗耳恭听。理想情况下,调制很容易手动实现,解调有一个我可以使用现有库的解调。因为这可以直接通过音频线而不是通过电话网络进行,理论上我们可以做得比 56kbps 或以前的标准更好,但实际上谁知道我们会得到什么。

感谢大家的关注,在/r/techsupportmacgyver在 /r/rust贡献了这么多出色的建议。我很快就会实现这个“调制解调器”,然后我会用一个结语来结束它。我想我可能会把我的代码放在某个地方,以便将来其他绝望的人使用——甚至可能是一个奇怪的渗漏工具库,这些工具很容易手动输入到一台快要报废的机器里?我们拭目以待。

更新 5:我花了很长时间与 ALSA 和我的廉价 StarTech USB 音频捕获设备(接收笔记本电脑上没有内置线路输入)作斗争,并多次尝试推出自己的传输协议,但最终在我的一些业余无线电爱好者朋友的建议下,我实现了RTTY 线路协议以 150 波特运行,实际上每秒大约能传输 10 字节。速度不是很快,但相当可靠。我几乎已经传输完了 820KB 文件,使用 CRC32 校验和进行了验证(使用 Pythonzlib模块中的 crc32 功能,我可以访问)。所以我宣布胜利,并想再次表示感谢!我会花更多时间寻找更多可读且可以传输的文件,但基础已经打好。和你们一起工作很有趣!

最后更新

在即将报废的机器上:

$ tar cf ./files
$ ./checksum.py ./files.tar 9999999
Part 1 checksum: -1459633665
$ ./zlib_compress.py ./files.tar
$ ./checksum.py ./files.tar.z 9999999
Part 1 checksum: -378365928
$ ./transmit_rust/target/debug/transmit ./files.tar.z
Transmitting files.tar.gz over audio using RTTY
Period size: 2048
Sample rate: 44100
Samples per bit: 294
Sending start signal.
Transmitting data.
nread: 2048
nread: 2048
...
nread: 2048
nread: 208
Transmission complete. Sending hold signal.

在救援机上:

$ minimodem --rx -8 --rx-one -R 44100 -S 915 -M 1085 --startbits 3
            --stopbits 2 --alsa=1 150 -q > ./files.tar.z
$ ./checksum.py ./files.tar.z
Part 1 checksum: -378365928
$ ./zlib_decompress.py ./files.tar.z
$ ./checksum.py ./files.tar
Part 1 checksum: -1459633665

:-)

答案1

这是一个示例 libasound 程序,它具有足够的定义来获得不带标题的基本 2 通道 44​​.1k wav 输出。

编辑:我实际上不确定直接将数据转储为 wav 是否可行,因为录制时的噪音很容易损坏它,但你可以做一些像高频正弦波这样的事情,这更可靠

EDIT2:如果 aplay 存在并且可以工作,您也可以使用它,只需编写一个输出原始音频的程序并将其输入到 aplay 或任何可以播放音频的程序中

EDIT3:修改它以根本不使用任何标题

如果 -lasound 无法编译,请添加 -L/path/where/libasound/is/located

/*
    gcc alsa_noheader.c -lasound
    cat stuff.wav | ./a.out
*/

typedef unsigned int uint;
typedef unsigned long ulon;

int printf(char*, ...);
void* malloc(long);
long read(int fd, void* buf, ulon count);

int snd_pcm_open(void**, char*, int, int);
ulon snd_pcm_hw_params_sizeof();
int snd_pcm_hw_params_any(void*, void*);
int snd_pcm_hw_params_set_access(void*, void*, int);
int snd_pcm_hw_params_set_format(void*, void*, int);
int snd_pcm_hw_params_set_channels(void*, void*, uint);
int snd_pcm_hw_params_set_rate_near(void*, void*, uint*, int*);
int snd_pcm_hw_params(void*, void*);
int snd_pcm_hw_params_get_period_size(void*, ulon*, int*);
long snd_pcm_writei(void*, void*, uint);
int snd_pcm_prepare(void*);
int snd_pcm_drain(void*);
int snd_pcm_close(void*);

int main(int argc, char* argv[])
{
    void* pcm;
    void* params;

    int rate;
    int nchannels;
    ulon frames;
    void* buf;
    int bufsize;
    long nread;

    snd_pcm_open(&pcm, "default", 0, 0);
    params = malloc(snd_pcm_hw_params_sizeof());
    snd_pcm_hw_params_any(pcm, params);

    /* 3 = rw_interleaved */
    snd_pcm_hw_params_set_access(pcm, params, 3);

    /* 2 = 16-bit signed little endian */
    snd_pcm_hw_params_set_format(pcm, params, 2);

    /* 2 channels */
    nchannels = 2;
    snd_pcm_hw_params_set_channels(pcm, params, nchannels);

    /* sample rate */
    rate = 44100;
    snd_pcm_hw_params_set_rate_near(pcm, params, &rate, 0);

    snd_pcm_hw_params(pcm, params);
    snd_pcm_hw_params_get_period_size(params, &frames, 0);

    bufsize = frames * nchannels * 2;
    buf = malloc(bufsize);

    /* read file from stdin */
    while (nread = read(0, buf, bufsize) > 0)
    {
        if (snd_pcm_writei(pcm, buf, frames) == -29)
        {
            printf("W: underrun\n");
            snd_pcm_prepare(pcm);
        }
    }

    snd_pcm_drain(pcm);
    snd_pcm_close(pcm);

    return 0;
}

答案2

您的 HDMI 或任何其他显示输出端口是否正常工作?如果正常工作,您可以使用屏幕捕获设备将其录制为视频并稍后处理。这样就不会受到网络摄像头帧速率的限制。

答案3

如何对数据进行十六进制编码并将其逐页输出到终端?

您可以添加一个带有二进制文件中偏移量的前缀,以便您可以轻松地重新生成页面(用于手动更正?)

然后在另一台计算机上使用一些 OCR 软件来扫描页面。

80x25 终端每页可产生 1000 个字节(减去前缀的一些空间)。因此,大约 1000 页即可获取数据。即使以每秒一页的速度,这也不到 20 分钟。

十六进制编码易于编写,并且还提供了原始形式的错误更正(只有 16 个有效符号)。

答案4

可能能够从命令行给自己发送电子邮件,包括发送文件。

就像是:

$ mail -s "Hello World" [email protected] < /tmp/urgentFileToSave.txt

应该管用。

更多示例: http://www.binarytides.com/linux-mail-command-examples/

相关内容