Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
#! /usr/bin/perl -w use strict; use Getopt::Mixed; use vars qw/$VERSION/; BEGIN { $VERSION = '1.0' } die "Not running as root!\n" if $<; my( $IS_UID, $OLD_ID, $NEW_ID, $RECURSE, $QUIET, $VERBOSE ) = ( 0, undef, undef, undef, undef, undef ); Getopt::Mixed::init( q{g=s gid>g group>g u=s uid>u user>u n=s new>n r recurse>r R>r q quiet>q v verbose>v V version>V }); OPTS: { # switch -u and -g are mutually exclusive my( $u_seen, $g_seen ) = (undef, undef); while( my( $option, $value, $pretty ) = Getopt::Mixed::nextOption( +) ) { $u_seen = 1 if $option eq 'u'; $g_seen = 1 if $option eq 'g'; $OLD_ID = $value if $option eq 'g' or $option eq 'u'; $IS_UID = 1 if $option eq 'u'; $NEW_ID = $value if $option eq 'n'; $RECURSE = 1 if $option eq 'r'; $QUIET = 1 if $option eq 'q'; $VERBOSE = 1 if $option eq 'v'; if( $option eq 'V' ) { print "$VERSION\n"; exit; } die "Cannot specify both -u and -g at the same time.\n" if defined $u_seen and defined $g_seen; } } my $id_name = $IS_UID ? 'user' : 'group'; defined $OLD_ID or die "Source ID not specified via -u/--user or via - +g/--group.\n"; $OLD_ID = resolve_id( $OLD_ID ) if( $OLD_ID !~ /^\d+$/ ); defined $NEW_ID or die "New $id_name ID not specified via -n/--new.\n" +; $NEW_ID = resolve_id( $NEW_ID ) if( $NEW_ID !~ /^\d+$/ ); if( $RECURSE ) { require File::Find; File::Find->import(); } local @ARGV = $RECURSE ? qw/./ : (do { opendir D, '.' or die "Cannot open directory . for input: +$!\n"; my @files = readdir D; close D; @files }) unless @ARGV; foreach my $spec ( @ARGV ) { if( $RECURSE ) { $VERBOSE and -d $spec and print "$spec\n"; find( sub { return if $_ eq '..'; try_chown( $_ ); }, $spec ); } else { try_chown( $spec ); } } sub resolve_id { my $text_id = shift; my $numeric_id = $IS_UID ? (getpwnam($text_id))[2] : (getgrnam($text_id))[2]; die "Can't determine $id_name ID for $text_id.\n" unless defined $numeric_id; $VERBOSE and print "numeric $id_name ID for $text_id resolves to $ +numeric_id.\n"; $numeric_id; } sub try_chown { my $file = shift; die "$file: no such file or directory.\n" unless -e $file; my( $uid, $gid ) = (stat $file)[4,5]; return unless defined $uid and defined $gid; if( $IS_UID and $uid == $OLD_ID) { print "\tchown $uid->$NEW_ID, $gid, $file\n" unless $QUIET; if( !chown $NEW_ID, $gid, $file ) { $QUIET or warn "Cannot change uid for $file from $uid to $ +NEW_ID: $!\n"; } } elsif( !$IS_UID and $gid == $OLD_ID ) { print "\tchown $uid, $gid->$NEW_ID, $file\n" unless $QUIET; if( !chown $uid, $NEW_ID, $file ) { $QUIET or warn "Cannot change gid for $file from $gid to $ +NEW_ID: $!\n"; } } } =head1 NAME nugid - new user/group id =head1 SYNOPSIS B<nugid> [B<-qrvV>] {B<-g> group|B<-u> user} -n ID [filespec] [filespe +c...] =head1 DESCRIPTION Selectively modify user and group ownerships of files and directories depending on current ownerships. All files that match the given group id or user id will be changed to the new specified id. Numeric and symbolic ids are recognised. =head1 OPTIONS =over 5 =item B<-g> B<--group> B<--gid> Group. Specifiy the existing group id (gid) to match. The id may eithe +r be numeric, or symbolic. In the latter case, it is an error to specify a non-exist +ant group name. This switch and the [B<-u>] switch are mutually exclusive. =item B<-u> B<--uid> B<--user> User. Specifiy the existing user id (uid) to match. The id may either +be numeric, or symbolic. In the latter case, it is an error to specify a non-exist +ant user name. This switch and the [B<-g>] switch are mutually exclusive. =item B<-n> B<--new> New. Specify the new id that will be applied to the files that are own +ed by the group or user specified via the B<-g> or B<-u> switches. =item B<-r> B<-R> B<--recurse> Recurse. All subdirectories of the directories specified on the comman +d line will be examined. =item B<-q> B<--quiet> Quiet. By default, the script will print out every change made as well + as errors resulting from the inability to perform the change. This switch will c +ause the script to run silently. =item B<-v> B<--verbose> Verbose. The script will print out a little more information than usua +l, notably the name of each directory root given when performing a recursive search, +and the resolved numeric id when a symbolic group or user is given. =item B<-V> B<--version> Version. Print out the current version of the script and exit with per +forming any changes. =back If no file specifications are given on the command line, one of two ac +tions will be taken. If recursion is specified then the current directory `.' wil +l be used as a starting point. If recursion is not specified, the current direct +ory is globbed and all entries are processed. The script must be run by the superuser, and will exit immediately if +this condition is not met. =head1 EXAMPLES C<nugid -u 1245 -n operator -rq /> Starting from the root directory, find all files who are owned by user + 1245 (which may be an account that has been deleted from the host) and chan +ge the ownership to that of the `operator' account. Nothing will be printed. C<nugid -g staff -n wheel> Change the files in the current directory that are owned by the group +`staff' to the group `wheel'. The output will look something like: chown 410, 5->15, ./porpentine chown 203, 5->15, ./slothrop chown 600, 5->15, ./stencil There may be many more files than these three in the current directory +, however, these would be the only ones belonging to the group `staff'. In this e +xample, the numeric id of the staff group is 5, and the id of the `wheel' grou +p is 15. C<nugid -g 45 -n 85 -r> Change all files owned by group 45 to group 85. Note that neither of t +hese ids necessarily equate to a known group name (as per C</etc/groups> or equ +ivalent). This may have dire consequences on the health of your host, use with c +aution. =head1 INSTALLATION As this this script is useable only by the superuser, it makes sense t +o install it with no permissions for anyone other than root. The following comma +nds are thus suitable for installing the script: cp thisfile /usr/local/bin/nugid chown root /usr/local/bin/nugid chmod 700 /usr/local/bin/nugid =head1 COPYRIGHT Copyright (c) 2001 David Landgren. This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR David "grinder" Landgren grinder on perlmonks ( eval {join chr(64) => qw[landgren]} =cut

In reply to nugid - new user/group ids by grinder

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    [Corion]: Meh. SQL window functions would even make pagination easy/trivial (but not performant), as rank() over (partition by user order by timestamp) / 10 as page would give me a page number for each item, with 10 items per page.
    [Corion]: Of course, the query performance for "all items on page 10" is likely worse than rank() between 100 and 109 , but if that means I can write 15 lines of SQL instead of needing to think about how to partition things and how to encode the page size...
    [Corion]: ... that would be nice. But alas, I'm currently tied to SQLite as minimum implementation, and it doesn't implement window functions :-(
    [Corion]: And I'm not aware of any other serverless SQL implementation that even reaches the capability of SQLite, not to mention surpasses it

    How do I use this? | Other CB clients
    Other Users?
    Others having an uproarious good time at the Monastery: (13)
    As of 2018-03-22 12:17 GMT
    Find Nodes?
      Voting Booth?
      When I think of a mole I think of:

      Results (274 votes). Check out past polls.