首先,我要坦白:不,我没有做应该做的备份。
二、情况:
我有一台戴尔 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 脚本来替换
cp
和cp -r
- 除非我找到某种方法来
/dev
为 SD 卡或 USB 驱动器创建条目,否则获取数据的最佳选择似乎是屏幕以及可能的扬声器/音频线。 - 我正在编写一个脚本来尝试读取文件并输出哪些文件是可读的。
仍然非常欢迎提出建议!
更新2:较新内容:
- 我在坏掉的电脑上写了一个 Python 脚本,它会逐位读取文件,并尝试通过在屏幕上闪烁一种或另一种颜色来传达这些位。现在它正在尝试执行一个两位代码,其中红色、绿色、蓝色和白色都代表一个两位对。不过,这种方法效果不太好,所以我可能会切换到两种颜色,一次执行一位。
- 在我的另一台笔记本电脑(我为了这台热门的新款 XPS 放弃了那台值得信赖的旧款 Thinkpad)上,我编写了一个使用 OpenCV Python 库从网络摄像头读取数据的脚本。其目的是让它解码另一台计算机发送的代码。问题是摄像头的帧速率大约是每秒 15 帧,这意味着如果我的传输完美无误,我的最大数据速率将是每秒 30 位,即每秒 225 字节。即每天 324k。
- 在即将报废的 XPS 上,我可以使用
tar
它将所需文件打包成一个 1.7 MB 的存档。不幸的是,、、gzip
和任何压缩实用程序都不可用。但使用 Python 的模块,我可以将此文件压缩到 820KB。考虑到这个大小,我可能可以在几天内将其发送过来。bzip2
xz
lzop
zlib
- 由于这种传输方法很容易出错,所以我将在 XPS 上实现汉明码,以便在传输数据时添加一些错误修正。
- 因为事情就是这样,所以可能会出现一些复杂情况,但至少获取这些数据似乎是可行的!
- 由于这仍然是一种非常糟糕的数据发送方式,我进一步研究了 USB 串行驱动程序。我尝试加载的模块(
usb-serial-simple
、、)给出了 I/O 错误。我也不认为它内置在内核中,因为不存在 /dev/ttyUSB* 设备。usb-debug
safe-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/