URL: https://linuxfr.org/users/freem/journaux/bout-de-code-pour-relancer-une-commande-dans-certaines-conditions Title: bout de code pour relancer une commande dans certaines conditions Authors: freem Date: 2020年04月22日T02:40:45+02:00 License: CC By-SA Tags: retry Score: 6 J'avais besoin d'un truc pour relancer une commande au plus un certain nombre de fois et attendre un certain temps entre deux exécution pour une bricole, alors j'ai pondu ça. Ça aurait pu me prendre 5 lignes de shell, mais c'est le genre de trucs que j'aime bien avoir sous le $PATH, et implémenter ça en vrai shell me semblais un peu du gâchis (à noter, [ça existe](https://github.com/kadwanev/retry)) J'ai fait quelques tests rapides, ça semble marcher, je pousserai plus demain pour voir si ça s'intègre bien dans mes scripts, en attendant je vous passe le source, dès fois que j'oublie alors que ça aurait pu servir a quelqu'un... ```C //Copyright 2020 // //Permission is hereby granted, free of charge, to any person obtaining a copy //of this software and associated documentation files (the "Software"), to deal //in the Software without restriction, including without limitation the rights //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell //copies of the Software, and to permit persons to whom the Software is //furnished to do so, subject to the following conditions: // //The above copyright notice and this permission notice shall be included in all //copies or substantial portions of the Software. // //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //SOFTWARE. //to build: //cc retry.c -o retry #include #include #include #include #include #include #include #include #define VERSION "0.1.0" #define CHECK_ERR() \ do {\ if( errno ){ \ fprintf( stderr, "[%d]: %s\n", __LINE__, strerror( errno ) ); \ return EXIT_FAILURE; \ }\ } while( 0 ) #define INT_ARG( ival ) \ do {\ ival = strtoul( val, &endptr, 0 );\ if( ival> INT_MAX || *endptr )\ { \ fputs( "invalid " #ival " value\n", stderr );\ return EXIT_FAILURE;\ } \ CHECK_ERR();\ } while( 0 ) int run_cmd( unsigned int time, unsigned int tsleep, char** cmd ); int print_bad_opt( char const* opt ); int print_version( void ); int print_help( int ret ); int main( int argc, char** argv ) { unsigned long count = 0; unsigned long pause_time = 0; unsigned long sleep_time = 0; char** arg = argv; char** cmd = argv + argc; char* endptr = 0; while( *arg ) { ++arg; if( !*arg || ( *arg && **arg != '-' ) ) { return print_bad_opt( *arg ); } char opt = (*arg)[1]; char* val = &(*arg)[2]; switch( opt ) { case '-': cmd = arg + 1; arg = argv + argc; break; case 'v': return print_version(); case 'h': return print_help( EXIT_SUCCESS ); case 's': INT_ARG( sleep_time ); val = endptr; break; case 't': INT_ARG( pause_time ); val = endptr; break; case 'c': INT_ARG( count ); val = endptr; break; default: return print_bad_opt( *arg ); } } if( !( *cmd ) ) { return print_help( EXIT_FAILURE ); } if( count == 0 ) { while( run_cmd( (unsigned)pause_time, (unsigned)sleep_time, cmd ) ) { } return EXIT_SUCCESS; } for( ; count && run_cmd( (unsigned)pause_time, (unsigned)sleep_time, cmd ); --count ) { } return count ? EXIT_SUCCESS : EXIT_FAILURE; } int run_cmd( unsigned int time, unsigned int tsleep, char** cmd ) { sleep( tsleep ); int status; switch( fork() ) { case 0: alarm( time ); execvp( *cmd, cmd ); case -1: CHECK_ERR(); break; default: break; } pid_t child = wait( &status ); return child != -1 ? WEXITSTATUS( status ) : -1; } int print_bad_opt( char const* opt ) { fprintf( stderr, "Unknown option: %s\n", opt ); return print_help( EXIT_FAILURE ); } int print_version( void ) { fputs( VERSION "\n", stderr ); return EXIT_SUCCESS; } int print_help( int ret ) { fputs( "retry [OPTIONS] -- command arguments\n" "\trun a command until it returns successfully.\n" "\t\n" "\tOptions:\n" "\t-v: print the version number of this program\n" "\t-h: print this screen\n" "\t-tTIME: if the command didn't return in TIME seconds, sends it SIGARLM. 0 means no limit.\n" "\t-cCOUNT: try running the command up to COUNT times. 0 means no limit.\n" "\t-sTIME: waits TIME seconds before executing command. 0 is invalid.\n" , ret == EXIT_FAILURE ? stderr : stdout ); return ret; } ``` Sur ce, bonne nuit. PS: si vous préférez mettre la licence en CC-0, ou autre trucs sans prise de tête, faites.

AltStyle によって変換されたページ (->オリジナル) /