Страницы

Поиск по вопросам

Показаны сообщения с ярлыком unix. Показать все сообщения
Показаны сообщения с ярлыком unix. Показать все сообщения

понедельник, 13 апреля 2020 г.

Как определить, жив ли процесс? Python 2.6, unix

#python #unix #процесс

                    
Вопрос тут появляется в похожем виде не впервые. Столкнулся со следующей проблемой:
нужно проверять не только существование процесса, но и то, что он не является зомби.
try:
    os.kill(pid, 0)
    return True
except OSError:
    return False

Вариант выше знаю, он не прокатывает с последним условием. Ставить внешние программы/модули
нельзя, все это происходит на разных машинах под линуксом и BSD, рутового доступа на
которые нету. Есть какие-нибудь варианты, как решить проблему?    


Ответы

Ответ 1



Можно чисто средствами баша ps aux | awk ' { print $2" "$8 } ' | grep -q "$pid Z" где $pid это pid вашего процесса. В случае если процесс зомби, то результат этой команды будет равен нулю, т.е. полное совпадение.

суббота, 11 апреля 2020 г.

Как убрать BOM из файла?

#файлы #unix #unicode

                    
Как консольно (в Unix-like окружении) удалить BOM (byte-order mark, непечатаемый
символ в самом начале файла, являющийся необязательной меткой юникода) из файла?
    


Ответы

Ответ 1



Например, с помощью awk: awk '{if(NR==1)sub(/^\xef\xbb\xbf/, "");print}' < oldfile > newfile

Ответ 2



Если точно знаете, что файл с BOM $ tail -c +4 newfile эффективно копирует все, пропустив первые 3 байта (см. man tail for details)

Ответ 3



С помощью sed: $ sed -e '1s/^\xef\xbb\xbf//' < bomfile > newfile Если заранее известно, что файл содержит BOM, то можно использовать dd: $ dd if=bomfile of=newfile bs=3 skip=1

четверг, 2 апреля 2020 г.

Что всё-таки означает загадочный символ . в bash?

#linux #bash #unix

                    
Почему символ . в зависимости от контекста выполняет разные задачи? Например в команде
cd . он выполняет роль текущей директории, а в команде . patch/activate является аналогом
команды source?

P.S наверное я дилетант, но это действительно ломает мне мозг
    


Ответы

Ответ 1



ни тот ни другой случай употребления не имеет прямого отношения к программе bash как таковой. cd — это определяемая стандартом posix утилита, которая вызывается как cd каталог и служит для изменения текущего каталога для процесса оболочки, её вызвавшего (все популярные posix-совместимые оболочки реализуют её как встроенную команду). в каждом (даже «пустом») каталоге есть как минимум два компонента (в терминах стандарта posix — entries): . и ... первый из них (.) — это ссылка на сам каталог, а второй (..) — это ссылка на «родительский» (т.е., предшествующий в файловой иерархии) каталог. поэтому команда cd . означает: «сменить текущий каталог на него же самого», т.е., фактически, не производит никаких изменений. . — это встроенная команда posix-совместимой оболочки, вызываемая как . файл и служащая для выполнения команд, содержащихся в файле, в контексте текущего процесса оболочки. подробнее см. ответ на соответствующий вопрос.

понедельник, 30 марта 2020 г.

Расшифровка команды cat **/c*

#unix #terminal #solaris


Помогите расшифровать команду. Я понимаю, что cat выводит файлы, c* это маска для
файлов, начинающихся на 'c', но что значит **/?
    


Ответы

Ответ 1



Это так называемый globstar - рекурсивный поиск во всех поддиректориях. Т. е. этот код выведет все файлы, начинающиеся на c, из всех директорий уровнем ниже данной. С одной звёздочкой команда была бы ограничена только поддиректориями текущей папки (т.е. abc/catalog, но не abc/cde/country). Но для работы этой опции нужно её включить соответствующей командой: $ shopt -s globstar https://www.linuxjournal.com/content/globstar-new-bash-globbing-option

Ответ 2



насчет 2-х звездочек перебор. А так, одна, любой подкаталог в текущем каталоге, в нем файлы начинающиеся с "C"

воскресенье, 15 марта 2020 г.

Как объединить 60000 файлов в один файл?

#bash #unix #объединение


В директории есть порядка 60000 текстовых файлов, их надо объединить в один файл.

Команда:

cat * > all.txt


не срабатывает:

-bash: /bin/cat: Argument list too long


Попробовал через:

find ./ -name '*.txt' | xargs grep '' > ../all.txt


но столкнулся с тем, что в all.txt записывается и путь, и название файла:

.//file1.txt:row1
.//file1.txt:row2
...


Какие еще могут быть варианты?
    


Ответы

Ответ 1



touch ../all.txt find ./ -name "*.txt" | xargs cat >> ../all.txt То есть cat каждого файла по отдельности, а не сразу всех в одной команде cat.

Ответ 2



воспроизводим ситуацию (у меня получилось с чуть большим количеством файлов): $ for i in $(seq 1 600000); do echo $i > $i.txt; done $ ls | wc -l 600000 $ cat *.txt > spisok bash: /bin/cat: Argument list too long будем добавлять содержимое в файл, который не подпадает под маску *.txt — это полезное условие, которое помогает избежать некоторых неприятностей. очень быстро и наиболее оптимально, вероятно, сделать примерно так (wc -l файл — это подсчёт количества строк в файле): $ find -name \*.txt -exec cat {} > spisok + $ wc -l spisok 600000 spisok $ head -n 3 spisok 200784 59591 584250 хм. файлы читались явно не по алфавитном порядку. если так не пойдёт, то придётся применить менее оптимальное решение с сортировкой и командой xargs: $ find -name \*.txt | sort | xargs -I{} cat {} > spisok $ wc -l spisok 600000 spisok $ head -n 3 spisok 100000 100001 100002 теперь файлы читаются (и записываются) по (алфавитному) порядку.

пятница, 13 марта 2020 г.

libpthread.so.0: error adding symbols: DSO missing from command line

#cpp #unix #boost #codeblocks


Пытаюсь использовать message_queue. Собственно код ничего не делает, кроме вызова
конструктора. 
Часть build log:


  /usr/bin/ld: obj/Debug/main.o: неопределённая ссылка на символ «pthread_condattr_setpshared@@GLIBC_2.2.5»
  //lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from
command line
  collect2: error: ld returned 1 exit status


using namespace boost::interprocess;

int main()
{ 
    message_queue(open_or_create,"message_queue" ,100 ,100);
}


Что происходит?
    


Ответы

Ответ 1



.../libpthread.so.0: error adding symbols: DSO missing from command line вот тут советуют добавить опцию -lpthread к опциям компилятора. для того, чтобы скомпилировать ваш пример, мне пришлось добавить первой строкой: #include и передать компилятору опции -lrt -lpthread. тогда программа test из файла test.cpp компилируется удачно: $ CPPFLAGS="-lrt -lpthread" make test g++ -lrt -lpthread test.cpp -o test описанная же вами ошибка легко воспроизводится при удалении опции -lpthread: $ CPPFLAGS="-lrt" make test g++ -lrt test.cpp -o test /usr/bin/ld: /tmp/cc8fR82D.o: undefined reference to symbol 'pthread_condattr_setpshared@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status : recipe for target 'test' failed make: *** [test] Error 1

воскресенье, 8 марта 2020 г.

Библиотека под unix для работы с изображениями

#cpp #изображения #unix


Подскажите пожалуйста либу под unix, которая позволит выполнять все функции с изображениям:
обрезать, склеивать, переворачивать, и т.д.

Желательно уже скомпилированную и с описанным API.
    


Ответы

Ответ 1



вопрос не по стандартам, но http://www.boost.org/doc/libs/1_61_0/libs/gil/doc/index.html http://www.imagemagick.org/Magick++/Image++.html - с чем в этом примере вы не смогли разобраться? еще более высокоуровневая либа http://cimg.eu/ что значит "уже скомпилированную"? если у вас проблемы со сборкой библиотеки с нуля - для убунты есть готовый пакет libmagick++-dev

Как в утилите find с атрибутом exec выполнить несколько операций с файлом

#linux #unix


Есть команда, состоящая из 2-ух частей, одинаковых циклов поиска, но с разными действиями
для найденных файлов.

sudo find '/tmp' -type d -exec chown root "{}" \; && sudo find '/tmp' -type d -exec
chmod a=trx,ug+w "{}" \;


Возможно ли её объединить, и если да, то как?

P.S. ... -exec chown root "{}" && chmod a=trx,ug+w "{}" \; не помогает, выводит:
find: missing argument to -exec'
    


Ответы

Ответ 1



Можно указать -exec несколько раз: find '/tmp' -type d -exec chown root {} \; -exec chmod a=trx,ug+w {} \;

вторник, 25 февраля 2020 г.

Как узнать, что именно разрешено делать через sudo?

#unix #sudo


Известно, что *nix-подобных ОС правила для sudo настраиваются в файле /etc/sudoers,
но если в нём много разных правил для разных пользователей, особенно если используются
алиасы/макросы, как удобно продиагностировать, что же именно разрешено делать через
sudo определённому пользователю?
    


Ответы

Ответ 1



Многие не знают, что sudo имеет встроенную возможность для удобной диагностики, для этого служит ключ -l: # sudo -l -U vasya-pupkin Runas and Command-specific defaults for vasya-pupkin: User vasya-pupkin may run the following commands on this host: (root) /usr/bin/tailf, /bin/ls, /usr/sbin/tcpdump (asterisk) NOPASSWD: /bin/mv Если вызывать sudo -l без дополнительных ключей, будут показаны разрешенные в sudoers команды для текущего пользователя. Используя дополнительный ключ -U username можно посмотреть разрешенные команды для любого пользователя в системе (но только если смотрящий - root). В приведённом примере пользователь vasya-pupkin может запускать tailf, ls и tcpdump от рута, а также от имени пользователя asterisk перемещать файлы (удобно, если нужно предоставить не-рутовому пользователю возможность манипулировать файлами, пренадлежащими третьему пользователю).

четверг, 13 февраля 2020 г.

Освобождение ресурсов, выделенных потоку

#c #память #unix #freebsd #pthread


Всем добрый день!
Хотелось бы обсудить следующую проблему : в программе средствами библиотеки pthread
создается поток, ОС выделяет ему некоторый обьем памяти на стек и т.п., после того,
как данный поток отработал и завершился, из другого потока вызывается pthread_join(),
забирающая код возврата. При этом, не заметно, чтобы память, выделенная для данного
потока, освобождалась (при вызове pthread_create() выделилось порядка 100 кб, из которых
ничего не освободилось ни после return(), ни после pthread_join()). Кто-нибудь может
пояснить, почему? Я что-то не так делаю, или это может быть обусловлено поведением ОС ?    


Ответы

Ответ 1



@margosh, я тоже (солидарно с @mikillskegg и почти интуитивно) считаю, что память, которую брал поток, используется повторно. Иллюстрацию приведу прямо здесь. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define fatal(msg) ({perror(msg); exit(-1);}) pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; int nth = 0; void * thcli (void *a) { pthread_mutex_lock(&lock); nth--; pthread_mutex_unlock(&lock); return (void *)1; } int main (int ac, char *av[]) { int i, n = av[1]? atoi(av[1]):100; if (n < 1) n = 100; pthread_t th[n]; void *res[n]; char buf[100]; do { pthread_mutex_lock(&lock); for (i = 0; i < n; i++) { if (pthread_create (&th[i], NULL, thcli, NULL)) fatal("create"); nth++; } printf ("run %d nth = %d\n",i,nth); pthread_mutex_unlock(&lock); for (i = 0; i < n; i++) { if (pthread_join (th[i], &res[i])) fatal("join"); } printf ("join %d nth = %d\nAgain ?\n",i,nth); } while (fgets(buf,sizeof(buf),stdin), buf[0] == 'y'); exit (puts("Bye") == EOF); } Обилия инклюдов не пугайтесь, большая часть на нужны, просто скопировал для этого тестика из другой программы. А вот и иллюстация avp@avp-xub11:~/src/ig/tst$ gcc th.c -pthread ..... avp@avp-xub11:~/src/ig/tst$ ./a.out 381 create: Cannot allocate memory avp@avp-xub11:~/src/ig/tst$ ./a.out 380 run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? . Bye avp@avp-xub11:~/src/ig/tst$ ./a.out 380 run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? . Bye avp@avp-xub11:~/src/ig/tst$ ./a.out 381 create: Cannot allocate memory avp@avp-xub11:~/src/ig/tst$ IMHO видно, что если ресурса почти достаточно, то после завершения потоков он опять высвобождается и повторно используется (по крайней мере в такой же ситуации). UPD-1 @margosh, у меня в линуксе не растет. Добавил функцию // returns second field for last line selected by 'what' static int pri_mem (int pid, char **what) { char path[1000]; int res = 0; sprintf (path,"/proc/%d/status",pid); FILE *in = fopen(path,"r"); if (!in) { perror(path); return; } while (fgets(path,1000,in)) { char **w = what; while (*w) { if (strncasecmp(path,*w,strlen(*w)) == 0) { fputs(path,stdout); char dummy[1000]; sscanf(path,"%s %d",dummy,&res); break; } w++; } } fclose(in); return res; } и чуть изменил main(), теперь печатает память перед каждым циклом avp@avp-xub11:~/src/ig/tst$ gcc th.c -pthread avp@avp-xub11:~/src/ig/tst$ ./a.out 380 VmPeak: 2252 kB VmSize: 2252 kB VmHWM: 312 kB VmRSS: 312 kB VmStk: 136 kB run 380 nth = 380 loop 0: join 380 nth = 0 Exit ? VmPeak: 3116732 kB VmSize: 35044 kB VmHWM: 2180 kB VmRSS: 680 kB VmStk: 136 kB run 380 nth = 380 loop 1: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 2: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 3: join 380 nth = 0 Exit ? и дальше VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 29: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 30: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 31: join 380 nth = 0 Exit ? y Bye avp@avp-xub11:~/src/ig/tst$ IMHO не растет. Попробуем с небольшим количеством потоков avp@avp-xub11:~/src/ig/tst$ ./a.out 30 VmPeak: 2252 kB VmSize: 2252 kB VmHWM: 316 kB VmRSS: 316 kB VmStk: 136 kB run 30 nth = 30 loop 0: join 30 nth = 0 Exit ? VmPeak: 248132 kB VmSize: 35044 kB VmHWM: 728 kB VmRSS: 628 kB VmStk: 136 kB run 30 nth = 30 loop 1: join 30 nth = 0 Exit ? VmPeak: 248136 kB VmSize: 35044 kB VmHWM: 740 kB VmRSS: 640 kB VmStk: 136 kB run 30 nth = 30 loop 2: join 30 nth = 0 Exit ? ....... ....... loop 15: join 30 nth = 0 Exit ? VmPeak: 248136 kB VmSize: 35044 kB VmHWM: 740 kB VmRSS: 640 kB VmStk: 136 kB run 30 nth = 30 loop 16: join 30 nth = 0 Exit ? VmPeak: 248136 kB VmSize: 35044 kB VmHWM: 740 kB VmRSS: 640 kB VmStk: 136 kB run 30 nth = 30 loop 17: join 30 nth = 0 Exit ? y Bye avp@avp-xub11:~/src/ig/tst$ Возможно проблема в FreeBsd.

Ответ 2



Странно, что никто не сказал про pthread_detach(). Помнится если его не запускать память выделенная под поток не освобождается и очень шустро растет, что очень заметно например в htop. Я вызываю эту штуку после pthread_create(). pthread_t restrict; if(pthread_create(&restrict, ...)) return 0; pthread_detach(restrict); return 0; "Функция pthread_join блокирует работу вызвавшей ее нити исполнения до завершения thread'а с идентификатором thread." Не вижу никакой связи с использованием памяти. Она тут не при чем.

Ответ 3



лимит комментов исчерпан. @avp, -D_THREAD_SAFE не спас. Возможно, прийдется пересмотреть логику очищения, в любом случае попробую и с detach для разнообразия, вдруг изменится чего. да, join сейчас только 1 поток делает, когда получает признак через pipe(), как Вы мне когда-то подсказали уже, за что большое спасибо :)

Доставка сигналов только одному потоку : может ли часть потеряться?

#c #unix #freebsd #pthread


Всем добрый день!
Если доставка некоторого сигнала разрешена только одному из потоков, может ли на
практике быть случай, когда несколько однотипных сигналов (SIGCHLD) будут посланы практически
одновременно, и процессор не успеет переключиться на данный поток вовремя, вследствии
чего обработчик сигнала выполнится 1 раз вместо, к примеру, 3-х ?     


Ответы

Ответ 1



Да, есть проблема. Если несколько сигналов SIGCHLD одновременно ждут доставки, будет доставлен лишь один сигнал. Источник. Там же рекомендация по обходу проблемы. Вот ещё, судя по всему, полезная информация по теме: handling SIGCHLD with multiple children.

Ответ 2



Может. В системе нет очереди сигналов, есть только битовая маска, приходящий сигнал выставляет там бит, при вызове обработчика (или действию по умолчанию) система сбрасывает этот бит.

Ответ 3



Не путаем понятия потоки (threads) и процессы (process). Процесс может содержать в себе несколько потоков (тредов или нитей). Если используешь сигналы, то он направляется конкретно процессу, а значит обработчику сигнала в этом процессе. man sigaction man signal

Как доставляется электронная почта?

#unix #sendmail #imap #pop3


Я вот не совсем понимаю, как идет доставка сообщений на почтовый сервер? Мы пишем
письмо с user@gmail.com на test@mail.ru. Что происходит на уровне системы? sendmail
(или другой мейл агент) доставляет письмо на указанный сервер (mail.ru) или на другой
(который прописан в mx-записи)? И самое главное - какому сервису он передается? sendmail-sendmail?
Pop3 и imap служат только для того чтобы отдавать почту пользователю? В общем сильно
не пинайте, а объясните концепцию или линк на толковую статью. Спасибо.
    


Ответы

Ответ 1



Предположим, мы написали письмо со своего ящика user@gmail.com для test@mail.ru. Из веб-формы письмо передаётся MTA (Mail Transfer Agent - почтовый агент) Google, который начинает его обработку. MTA может быть любым - sendmail, postfix, MS Exchange и т.п., порядок действий везде одинаковый. Вначале MTA выделяет из адреса отправителя имя домена (в нашем случае - mail.ru) и посылает DNS-запрос "какие MX-записи у этого домена?". Дело в том, что для почты есть свои собственные записи в DNS, так называемые MX-записи (MX - Mail Exchanger), в которых находятся имена (не IP-адреса, а именно имена почтовых серверов домена!). В ответ DNS присылает список имён почтовых серверов. MTA берёт один из полученных имён и посылает DNS-запрос "какой IP у этого имени?". DNS-сервер присылает в ответ адрес (возможно, не один) для имени, после чего MTA соединяется с этим адресом и по стандарному протоколу SMTP (или ESMTP) передаёт письмо почтовому серверу получателя. Сервер получателя кладёт письмо в своё внутреннее хранилище писем для test@mail.ru и ждёт пока пользователь подключится и прочитает свою почту. Пользователь может не использовать web-интерфейс, а подключаться к MTA при помощи отдельной программы - почтового клиента (Mozilla Thunderbird, The Bat и т.п.). Но всё дело в том, что протокол SMTP для этого не подходит, он создан для обмена данными между серверами. Здесь работают два других протокола - POP3 и IMAP. Для клиента разница между ними почти отсутствует, но внутренне они абсолютно непохожи. IMAP более современный и умный, POP3 более старый и поглупее. (Если есть возможность - выставляйте IMAP.) Эти протоколы ответственны за передачу почты между клиентской программой и MTA. Если SMTP однонаправленный (только отправка), то клиентские протоколы двунаправленные (отправка и получение). Есть ещё одна интересная деталь. MX-записей у домена может быть несколько. То есть у домена может быть несколько почтовых серверов. Казалось бы зачем это надо? Ведь у любого DNS-имени может быть несколько IP-адресов (A-записей), так зачем же усложнять картину? А затем, что у MX-записей есть то, чего нет у A-записей - приоритет. Все IP для одного имени равноприоритетны, но для MX-записей можно указывать их "вес". "Вес" - это неотрицательное целое число и чем оно меньше, тем выше приоритет этой записи. MTA всегда вначале пытается соединиться с сервером, имеющим более высокий приоритет и только если ему это не удалось, переходит к серверу с более низким приоритетом.

воскресенье, 9 февраля 2020 г.

Как изменить права доступа по умолчанию Unix.

#ubuntu #unix


Подскажите, как изменить права доступа для файлов по умолчанию. Для каталогов стоит
777, для файлов 666.
Мне необходимо для файлов поставить по умолчанию 777 при создании. Как это сделать?
    


Ответы

Ответ 1



Мне необходимо для файлов поставить по умолчанию 777 при создании. Как это сделать? если коротко, то — никак. длинное изложение — ниже, а в конце упомянуты соображения по поводу того, «что, если очень хочется…». в конечном (для процесса) итоге файл/каталог создаётся функцией open() (см. $ man 1 open и упоминание в posix). при этом во втором аргументе должен быть передан (в том числе и) бит O_CREAT (для каталога — ещё и O_DIRECTORY), а третьим аргументом должен идти набор бит, задающих разрешения процессам (в зависимости от того, от чьего имени они действуют) на доступ к создаваемому файлу/каталогу. но указанный набор бит — не «окончательный приговор». как минимум на него может оказать влияение file mode creation mask (umask) — свойство процесса (наследуемое дочерними процессами), указывающее, какие биты разрешений надо скрыть («замаскировать») у создаваемого файла/каталога. именно «скрыть», но не добавить. отсюда, надеюсь, становится чуть понятнее, почему, если мы указали процессу «ничего не скрывать» (т.е., umask a=rwx, или, в числовом виде — umask 0), каталог создаётся с битами исполнимости, а файл всё равно — без этих битов: процесс просто не запрашивал установку этих битов при вызове функции open(). почему же не запрашивал? потому что создатели данной конкретной программы, породившей запущенный вами процесс, руководствовались стандартом posix: When a file that does not exist is created, the following features defined in the System Interfaces volume of POSIX.1-2008 shall apply unless the utility or function description states otherwise: ... 3. If the file is a regular file, the permission bits of the file shall be set to: S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP | S_IRUSR | S_IWUSR (see the description of File Modes in XBD Headers, ) except that the bits specified by the file mode creation mask of the process shall be cleared. If the file is a directory, the permission bits shall be set to: S_IRWXU | S_IRWXG | S_IRWXO мой вольный перевод: когда создаётся файл, который до этого не существовал, следующие возможности (features) должны быть применены (если иное не не отмечено в описании утилиты или функции): ... 3. если это обычный файл, должны быть выставлены следующие биты разрешений: S_IROTH | S_IWOTH | S_IRGRP | S_IWGRP | S_IRUSR | S_IWUSR (см. описание file modes в ) за исключением тех битов, которые должны быть скрыты (удалены) согласно значению file mode creation mask (umask) процесса. если файл является каталогом, должны быть выставлены биты: S_IRWXU | S_IRWXG | S_IRWXO или, чуть проще: обычные файлы должны иметь биты a=rw (синонимы: ugo=rw и u=rw,g=rw,o=rw), в числовом виде — 0666 (в восьмиричной системе счисления) каталоги должны иметь биты a=rwx (синонимы: ugo=rwx и u=rwx,g=rwx,o=rwx), в числовом виде — 0777 (в восьмиричной системе счисления) биты, указанные в umask, должны быть скрыты (удалены) так можно ли изменить такое (подчиняющееся стандарту) поведение программ? теоретически — можно. известные мне варианты: изучите документацию к программе (или её исходный код). возможно, ей можно указать (например, через конфигурационные файлы) создавать файлы с нужным вам набором бит (т.е., переопределять третий аргумент функции open()). программу можно пересобрать, исправив умолчальное значение набора бит. можно воспользоваться каким-нибудь монитором изменения файлов (например, подсистемой inotify программы linux) или какой-то аналогичной «пост-обработкой».

Ответ 2



Для каждого пользователя linux можно задать маску которая будет устанавливать права на новые файлы и папки по умолчанию например: umask 777 На все файлы и папки при создание будет стоять 777 Все просто вроде... Ссылки для просвещения: wiki Подробние и с примерами на все случаи

Экранирование специалных символов для аргументов SSH команды

#unix #shell #символы #экранирование


Задача:


Переменная, содержит в конце $$

$ a='SYS_$$'

$ echo $a

SYS_$$

Тут разворачивает $$ в конце строки как номер процесса, а надо отобразить строку
"SYS_$$", передаваемую как параметр.

$ echo "echo \$1" | ssh another_host "/bin/sh -s $a"

SYS_18992


    


Ответы

Ответ 1



Попробуйте так: $ a='SYS_$$' $ echo 'echo $1' | ssh another_host "/bin/sh -s '$a'" SYS_$$ При вызове ssh, внутри двойных кавычек одиночные кавычки тетряют своё специальное назначение и переменная $а будет замещена её значением, т.е. $SYS_$$. Далее, при вызове sh на удалённом хосте, одиночные кавычки вновь приобретают своё специальное назначение и препятствуют замещению $$ текущим pid.

Ответ 2



надо передать символы одинарных кавычек вокруг аргумента, с которым вызывается программа sh. для этого надо добавить перед кавычками символы \: $ v='a$$'; echo 'echo $1' | ssh хост sh -s \'$v\' a$$

суббота, 8 февраля 2020 г.

Способы определить утечку памяти

#c #unix #memory_leaks #linux


Суть вопроса проста. Какие способы/инструменты есть для определения что память у
нас утекла?
ANSI C.
Для Unix-подобных ОС
x64-86
Нагуглил Hans Boehm garbage collector, но он то ли не работает с Linux x64, то ли
я совсем его криво использую - всё время выдаёт 65536 на GC_get__heap_size().

crtdbg не подходит из-за привязки к MSVS.
Изначально это была задача определить правильно ли я удаляю дерево, но переросло
в этот вопрос.    


Ответы

Ответ 1



Попробуйте Valgrind. Одна из программ Valgrinda, Memcheck, насколько я понимаю, соответствует вашим требованиям.

среда, 5 февраля 2020 г.

Email рассылка нескольким получателям командой mailx в Linux

#linux #unix


В Линукс через командную строку запускается рассылка email нескольким получателям:

$ echo "This is message body" | mail -s "This is Subject" someone1@example.com,someone2@example.com


Можно ли сделать так, чтобы каждый реципиент при получении письма в поле "Кому:"
видел только себя, а не всех тех кому также рассылаются письма?
    


Ответы

Ответ 1



Особенности SMTP протокола таковы, что для выполнения условия: чтобы каждый реципиент при получении письма в поле "Кому:" видел только себя, а не всех необходимо отправить письмо каждому получателю отдельно. Не важно, делаете вы это через программу mail в консоли, или используете язык программирования. Поэтому, если нужно использовать консольный вариант с рассылкой по списку, то пишите скрипт с циклом по всем получателям. Если же очень надо это делать одной командой, то воспользуйтесь маленьким "лайфхаком". Обычно называется forward. Реализовать это можно по разному. Например, создать в файле /etc/aliases такую строку: managers: user1, user2, user3 или managers: user1@your-domain.com, user2@your-domain.com, user3@your-domain.com и слать письмо на адрес managers@your-domain.com. Но тут есть особенность: все получатели такого письма увидят в поле Кому адрес managers@your-domain.com.

Ответ 2



Типы получателей письма Cc: (копия, carbon copy) — вторичные получатели письма, которым направляется копия. Они видят и знают о наличии друг друга. Типы получателей письма Bcc: (скрытая копия, blind carbon copy) — скрытые получатели письма, чьи адреса не показываются другим получателям. Из этого следует, что -b - это Bcc, а -c - Сс Поэтому, соответственно, добавьте флаг -b или -c перед адресами: echo "This is message body" | mail -s "This is Subject" -b someone1@example.com,someone2@example.com echo "This is message body" | mail -s "This is Subject" -c someone1@example.com,someone2@example.com В связи с комментарием мистера @de_frag, данный ответ является useless. По этой причине, в дальнейшем я найду рабочий (корректный) вариант, и отредактирую ответ.

понедельник, 3 февраля 2020 г.

Почему не сходится du -h и du -b?

#linux #bash #unix


ПОчему не сходится вывод du -h и du -b?

$ du -h файл
12k
$ du -b файл
8738

    


Ответы

Ответ 1



читаем man du про опцию -b: -b, --bytes equivalent to `--apparent-size --block-size=1' читаем там же про опцию --apparent-size: --apparent-size print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in (`sparse') files, internal fragmentation, indirect blocks, and the like мой вольный перевод: выводит «видимые» (apparent) размеры файлов вместо используемого дискового пространства; хотя «видимый» размер обычно меньше, он может быть больше из-за пустого места в «дырявых» (sparse) файлах, внутренней фрагментации, косвенных блоков и т.п. проверяем, что --apparent-size даёт в реальности (создаём файл, содержащий 8738 байтов 0x00): $ dd if=/dev/zero of=file1 bs=1 count=8738 8738+0 records in 8738+0 records out 8738 bytes (8.7 kB) copied, 0.0111545 s, 783 kB/s $ du -b file1 8738 file1 $ du -h file1 12K file1 $ du -h --apparent-size file1 8.6K file1 а на файле, который вообще пуст (т.н. «дырявый», sparse), получается ещё наглядней: $ truncate -s 8738 file2 $ du -b file2 8738 file2 $ du -h file2 0 file2 $ du -h --apparent-size file2 8.6K file2 а откуда, собственно, цифра 12K? она кратна размеру блока на диске: место под файл отводится блоками. в вашем случае, вероятно, в районе 4K. уточнить для файловых систем ext* можно, например, так: $ sudo tune2fs -l /dev/sda1 | grep -i 'block size' Block size: 4096 где /dev/sda1 — раздел, на котором находится этот самый рассматриваемый файл.

пятница, 31 января 2020 г.

Как вывести файлы названием которых содержит меньше пяти символов скажем? unix

#ubuntu #unix


Как вывести файлы название которых содержит меньше пяти символов скажем?
    


Ответы

Ответ 1



find /your_path -type f -print| awk -F/ ' length($NF) < 5 '

Ответ 2



Утилита find умеет в регулярные выражения, и можно обойтись без вызова сторонних программ. find -regextype egrep -regex '.*/.{,5}' Первые три символа в шаблоне нужны из-за того, что -regex применяется ко всему пути, а мы хотим найти файлы, анализируя лишь их имя безотносительно местоположения. Кроме того, мы задали ключ -regextype, чтобы упростить наше регулярное выражение. Обратите внимание, в регулярке мы записали пятёрку, что означает нестрогое сравнение. То есть команда выше выведет имена файлов, в которых не более пяти символов. Чтобы обеспечить точное соответсвие условию в вопросе, нужно заменить 5 на 4. (Но это уже будет не так интересно).

Ответ 3



Пример с grep: find ~ -type f | grep -P '/.{5}$'

среда, 22 января 2020 г.

Lock file in unix(Solaris)

#c #файлы #unix #exec #solaris


Вопрос следующий: в man-е Solaris написано, что захват файлов наследуется при exec,
однако, когда я захватываю файл на запись, а затем вызываю execlp(...) — открываю файл
в редакторе. Затем я создаю новую сессию и запускаю ту же программу, по идее процесс
должен остановиться в ожидании из-за флага F_SETLKW в fcntl(), но он также открывает
редактор... В чем может быть дело? 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define editor "nano"

int main(int argc, char *argv[]) {
    struct flock lock;
    int fd;

    if ((fd = open(argv[1], O_RDWR)) == -1) {
            perror("Cannot open file");
            exit(EXIT_FAILURE);
    }
    lock.l_type = F_WRLCK;
    lock.l_whence = SEEK_SET;
    lock.l_start = 0;
    lock.l_len = 0;

    if (fcntl(fd, F_SETLKW, &lock) == -1) {
            perror("fcntl failed");
            exit(EXIT_FAILURE);
    }

    execlp(editor, editor, argv[1], NULL);
    perror("exec is not working");
    exit(EXIT_FAILURE);

}

    


Ответы

Ответ 1



man 2 fcntl (Solaris) All locks associated with a file for a given process are removed when a file descriptor for that file is closed by that process or the process holding that file descriptor terminates В linux этот момент расписан более подробно: man 2 fcntl (Linux [man-pages-ru]) Если процесс закрывает любой файловый дескриптор, ссылающийся на файл, то освобождаются все блокировки процесса для этого файла, независимо от файлового дескриптора(ов), на который получена блокировка. Это плохо: это означает, что процесс может потерять свои блокировки на файл, такой как /etc/passwd или /etc/mtab, когда какой-либо причине библиотечная функция решает их открыть, прочитать и закрыть. В данном случае происходит следующее: nano открывает тот же файл, на который удерживается блокировка (на другом дескрипторе), читает его и закрывает. В момент закрытия блокировка теряется, как и описано выше.

воскресенье, 12 января 2020 г.

Работа с AF_UNIX SOCK_DGRAM SO_BROADCAST сокетом

#c #сокет #unix #select #unix_socket


Здравствуйте, пишу чатик, начал с параллельного эхо-сервера.
Теперь пытаюсь сделать так, чтобы сообщения от одного подключенного клиента рассылались
всем подключенным клиентам.
В процессе-родителе создаю сокет в файловом пространстве, и делаю его широковещательным:
  int commfd;
  struct sockaddr commaddr;

  if( ( commfd = socket( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 )
    perror( "error in common socket" );

  bzero( &commaddr, sizeof( commaddr ) );
  commaddr.sa_family = AF_UNIX;
  strcpy( commaddr.sa_data, COMM_SOCK_NAME );

  if( bind( commfd, &commaddr, sizeof( commaddr ) ) < 0 )
    perror( "error in bind for commfd" );

  int n=1;
  if( setsockopt( commfd, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n) ) < 0 )
    perror( "error in setsockopt" );

И в дочернем процессе-обработчике клиента подключаюсь к этому сокету, и через select
жду, пока сокет этот будет доступен на чтение. 
В общем суть задумки: клиент пишет сообщение серверу (а на сервере для этого клиента
свой процесс-обработчик), это сообщение отсылается назад этому же клиенту, и это же
сообщение пишется в широковещательный сокет. В это же время процессы - обработчики
других клиентов ждут того самого сообщения, принимают, и выводят на экран.
Но не срабатывает select в обработчике, что я не так делаю?
Весь код сервера здесь: http://paste.ubuntu.com/7617694/    


Ответы

Ответ 1



UNIX-cокеты не поддерживают широковещательную передачу. Приём-передача широковещательных udp-пакетов осуществляется с использованием (кроме опции SO_BROADCAST) широковещательных адресов, которые не предусмотрены в AF_UNIX. Так же невозможно забиндить более одного сокета на один AF_UNIX-адрес, что потребовалось бы для приёма.