Создание скрипта переименования [закрыто]

Logré crear un script de inicio simple que ejecuta ps fpara obtener el árbol de procesos. Me da un buen resultado diciéndome todo lo que necesito:

PID TTY      STAT   TIME COMMAND
281 tty1     Ss     0:00 -bash
383 tty1     S+     0:00  \_ mc
385 pts/0    Ss     0:00      \_ bash -rcfile.bashrc
408 pts/0    R+     0:00          \_ ps f

Analizarlo desde la última línea me lleva a procesar con un TTY=tty1 real (por supuesto que es culpablemc). Así que finalmente puedo ejecutar mi programa con el número tty de mc analizado como argumento.

Otra opción sería recuperar el número de tty dentro de mi programa analizando los archivos '/proc/PID/stat' como lo hace el programa psque contiene tanto el id de tty dev como el id del proceso principal. Pero el uso de secuencias de comandos me hace sentir que depende menos del sistema operativo. Muestra '/proc/PID/stat' a continuación:

383 (mc) R 281 383 281 1025 383...
            |            |_ TTY:  test major bits for type and minor for id
            |______________ PPID: use to traverse tree 

Así que al final se me ocurrió este código:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <gpm.h>

static int find_tty()
{
    char buf[256];
    char* ptr;
    FILE* f;
    int r;
    char stat;
    int ppid,pgrp,sess,tty;

    int pid = getpid();

    while (pid>0)
    {
        sprintf(buf,"/proc/%d/stat",pid);
        f = fopen(buf,"r");
        if (!f)
            return 0;
        r = fread(buf,1,255,f);
        fclose(f);
        if (r<=0)
            return 0;
        buf[r] = 0;
        ptr = strchr(buf,')');
        if (!ptr || !ptr[1])
            return 0;
        r = sscanf(ptr+2,"%c %d %d %d %d", &stat,&ppid,&pgrp,&sess,&tty);
        if (r!=5)
            return 0;
        if ( (tty&~63) == 1024 && (tty&63) )
            return tty&63;
        pid = ppid;
    }
    return 0;
}

int main(int argc, char* argv[])
{
    Gpm_Connect gpm_connect;
    //...

    int gpm = Gpm_Open(&gpm_connect,find_tty()/*0*/);
    //...
}
-8
16.12.2018, 05:51
2 ответа

Инструмент rename является крайне непортативным; нет почти ничего общего между версией rename для семейства RHEL/CentOS/Fedora и версией, найденной в Ubuntu или Debian.

Я написал ответ с примерами использования обеих версий rename некоторое время назад.

Вы не сказали, какую ОС вы используете, поэтому трудно быть очень конкретным - и поскольку это домашнее задание, вы должны поработать над ним сами, поэтому я не буду писать ответ, даже если вы скажете, какую ОС.

Однако, пара советов:

  • sed работает с содержимым текстового файла; он не изменяет имя файла и уж тем более имя каталога. Его нельзя использовать для этого, и именно поэтому вы получаете ошибки от команды, которую вы написали.
  • Вы на правильном пути с вашей командой find.
  • Советую вам поискать операторы -name и -iname для find, так как они могут пригодиться (не нужно пытаться переименовывать файлы, которые не соответствуют заданному шаблону).
  • Использование -exec с rename (соответствующей версии для вашей ОС), вероятно, является самым простым/лучшим решением для этого.
1
28.01.2020, 05:21

Можно использовать инструмент rename. Пример такого использования:

rename section chapter *

Или в вашем случае вы, вероятно, передадите вывод find.

find . -type d -print | xargs rename section chapter
-1
28.01.2020, 05:21

Теги

Похожие вопросы