Из справочной страницы sudo
:
-i, --login
Run the shell specified by the target user's password data-
base entry as a login shell.
Ваш userB имеет / bin / false
в качестве оболочки, поэтому эта команда запущен.
% /bin/false ; echo $?
1
Чтобы исправить это, вам нужно изменить оболочку пользователя B на / bin / bash
(или / bin / sh
или как вам больше нравится) или не используйте флаг -i
для sudo. Вам нужна оболочка входа?
Ниже приводится быстрый способ взлома небольшой программы на C, способной сравнивать два файла (файл1, файл2) поблочно и, если блоки разные, копирует соответствующий блок из файла1 в файл2. Также работает для файлов и блочных устройств. Делайте с ним что хотите, но на свой страх и риск!
/*
Small program to blockwise compare two files and write different
blocks from file1 to file2.
Arguments: file1, file2, blocksize in bytes
If blocksize is not given, it is set to 512 (minimum)
No error checking, no intensive tests run - use at your own risk!
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(argc, argv)
int argc;
char *argv[];
{
char *fnamein; /* Input file name */
char *fnameout; /* Output file name */
char *bufin; /* Input buffer */
char *bufout; /* Output buffer */
int bufsize; /* Buffer size (blocksize) */
int fdin; /* Input file descriptor*/
int fdout; /* Output file descriptor*/
int cnt; /* Current block # */
/* Argument processing */
if (argc < 3 || argc > 4) {
fprintf(stderr,"Usage: %s infile outfile [bufsize]\n", argv[0]);
exit(1);
}
fnamein = argv[1];
fnameout = argv[2];
if (argc == 4) {
bufsize = atoi(argv[3]);
if (bufsize < 512) {
fprintf(stderr,"Error: Illegal value for [bufsize]: %s\n", argv[3]);
exit(1);
}
} else {
bufsize = 512;
}
fprintf(stderr, "Copying differing blocks from '%s' to '%s', blocksize is %i\n", fnamein, fnameout, bufsize);
if (! ((bufin = malloc(bufsize)) && (bufout = malloc(bufsize)))) {
fprintf(stderr,"Error: Can't allocate buffers: %i\n", bufsize);
exit(1);
}
fdin = open(fnamein, O_RDONLY);
if (fdin < 0) {
fprintf(stderr,"Error: Can't open input file: %s\n", fnamein);
exit(1);
}
fdout = open(fnameout, O_RDWR | O_SYNC);
if (fdout < 0) {
fprintf(stderr,"Error: Can't open ouput file: %s\n", fnameout);
exit(1);
}
cnt = 0;
while (read(fdin, bufin, bufsize) == bufsize) {
if (read(fdout, bufout, bufsize) == bufsize) {
if (memcmp(bufin, bufout, bufsize) != 0) {
fprintf(stderr, "Differing blocks at block # %i; writing block to %s\n", cnt, fnameout);
if (lseek(fdout, -bufsize, SEEK_CUR) > -1) {
if (write(fdout, bufin, bufsize) != bufsize) {
fprintf(stderr,"Error: Unable to write to output file %s block # %i\n", fnameout, cnt);
exit(1);
}
} else {
fprintf(stderr,"Error: Unable to seek to output file %s block # %i\n", fnameout, cnt);
exit(1);
}
}
} else {
fprintf(stderr,"Error: Unable to read from ouput file %s block # %i\n", fnameout, cnt);
exit(1);
}
cnt++;
}
exit(0);
}
Ну, как упоминалось в комментарии к вашему вопросу, dd
параметры bs
, seek
, skip
и count
- ваши друзья. Кроме того, я бы логично разделил ваши изображения на список фрагментов подходящего размера (скажем, по 10 МБ каждый) и поддержал бы md5sum каждого фрагмента (или более длинный хэш, если вы опасаетесь коллизий, чего я бы не стал). Когда появляется новый образ, вам нужно только проверить новый образ по хэшам (практически вдвое сократить время сравнения) и скопировать на диск только измененные фрагменты. Вы даже можете обнаружить, что некоторые из ваших фрагментов идентичны (возможно, все нули), и соответствующим образом выполнить дальнейшую оптимизацию.
Рассмотрите qemu-img, используя оригинал в качестве резервного файла и создавая диск с разницей в формате qcow2.
Доступ к нему как к блочному устройству с помощью qemu-nbd (для преобразования его в устройство nbd).
Это позволит записать дельты на дифференцирующий диск qcow2 и оставить оригинал в покое. Дифференцирующий диск увеличивается на небольшие значения для каждого измененного блока.
Чтобы затем применить эти отклонения к одному или нескольким "оригиналам", используйте операцию "commit" qemu-img.