{"id":13491060,"url":"https://github.com/skx/sysadmin-util","last_synced_at":"2025-10-03T22:30:35.980Z","repository":{"id":8020808,"uuid":"9429764","full_name":"skx/sysadmin-util","owner":"skx","description":"Tools for Linux/Unix sysadmins.","archived":true,"fork":false,"pushed_at":"2020-03-30T06:57:46.000Z","size":112,"stargazers_count":954,"open_issues_count":0,"forks_count":112,"subscribers_count":44,"default_branch":"master","last_synced_at":"2024-09-29T18:41:19.902Z","etag":null,"topics":["bash","c","perl","sysadmin","utilities"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"skx","custom":"https://steve.fi/donate/"}},"created_at":"2013-04-14T14:02:12.000Z","updated_at":"2024-09-23T20:47:28.000Z","dependencies_parsed_at":"2022-08-26T04:01:24.596Z","dependency_job_id":null,"html_url":"https://github.com/skx/sysadmin-util","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fsysadmin-util","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fsysadmin-util/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fsysadmin-util/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skx%2Fsysadmin-util/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skx","download_url":"https://codeload.github.com/skx/sysadmin-util/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235198387,"owners_count":18951497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","c","perl","sysadmin","utilities"],"created_at":"2024-07-31T19:00:53.195Z","updated_at":"2025-10-03T22:30:30.728Z","avatar_url":"https://github.com/skx.png","language":"Perl","readme":"sysadmin-utils\n============\n\nThis repository contains a small collection of scripts that might be\nuseful to sysadmins.  I put it together myself to centralise the small\ntools that I find useful, and it seems to be popular.\n\nI used to solicit the inclusion of new tools, but have slowly come\nto realize that \"less is more\".  I __love__ the idea of sysadmins,\ndevelopers, and other people building up their own toolkits, but also\nfind that people submit things that I just don't understand the appeal of.\n\nIt makes sense that personal-tools are very personal, but it does mean\nrejection is almost always the default behaviour and that makes me feel\nbad.\n\nInstead of adding things here consider this repository a small collection of things that I use, and if you want to take some/all of utilities into your own use then please do so.  If not then I would __strongly__ encourage you to consider what tools would make your daily-life more useful and then collect them, __document__ them, and publish them yourself.\n\n\nIn short the value here is the __idea__ of collecting your commonmost utilities and making them easy to install and update from one central-source.  Not the specific tools themselves.\n\nThere is a replacement repository which is still open, and which new additions can be made more freely:\n\n* https://github.com/skx/sysbox\n\n\n\nago\n---\n\nShow how long ago a file/directory was modified in a  human-readable fashion.\n\nExample:\n\n     $ ./ago /etc/passwd\n     /etc/passwd 15 weeks ago\n\nAlternatives:\n\n* `stat` and `ls` both show ages, but not in a human-readable fashion.\n\n\n\nchronic\n-------\n\nRun a command, hiding STDOUT and STDERR if it completes successfully.\n\nExample:\n\n     ./chronic cp /etc/passwd /tmp/not/found\n\nThis is designed to be used for cron-jobs, where output is generally\nignored in the case of success.\n\nThis was written by Joey Hess and is part of [moreutils](https://joeyh.name/code/moreutils/).\n\n\n\ncidr2ip\n-------\n\nGiven a set of CIDR ranges output the individual IPs in the range(s).\n\nExample:\n\n     $ ./cidr2ip 192.168.0.0/24\n     192.168.0.0\n     192.168.0.1\n     192.168.0.2\n     192.168.0.3\n     192.168.0.4\n     ..\n\n\n\n\ncollapse\n--------\n\nRemove extraneous whitespace from lines, and remove empty-lines entirely.\n\nExample:\n\n     $ echo -e \"Test1\\n    f  \\n\\nTest2\\n\\n\\n\\n\" | ./collapse\n     Test1\n     f\n     Test2\n\nAlternatives:\n\n* `tr`\n* ...\n\n\n\ndupes\n-----\n\nReport on duplicate files, via a SHA1 hash of the contents, recursively.\n\nExample:\n\n    $ dupes\n    ./.git/logs/HEAD\n\t./.git/logs/refs/heads/master\n    ./.git/refs/heads/master\n\t./.git/refs/remotes/origin/master\n\nAlternatives:\n\n* [fdupes](http://packages.debian.org/fdupes)\n* [fslint](http://packages.debian.org/fslint)\n* [duff](http://packages.debian.org/duff)\n* [rdfind](http://packages.debian.org/rdfind)\n\n\n\nempty-dir\n---------\n\nIndicate, via return code, whether a given directory is empty or not.\n\nExample:\n\n    if empty-dir /etc; then echo \"We're broken\" ; fi\n\n\n\nexpand-ipv6\n-----------\n\nExpand an abbreviated/compressed IPv6 address to the full-form.\n\nExample:\n\n     ./expand-ipv6 fe80::1 2001:41c8:10b:103::111\n     fe80:0000:0000:0000:0000:0000:0001\n     2001:41c8:010b:0103:0000:0000:0111\n\nAlternatives:\n\n* `sipcalc`\n* ...\n\n\n\ngraphite_send\n-------------\n\nA simple script to send a consistent set of metrics \u0026 values to a remote\ngraphite instance.\n\nThe metrics may be extended via small \"plugins\", which are nothing more\nthan shell/perl/ruby/python scripts in a particular directory.\n\nExample:\n\n     graphite_send -v\n\n**NOTE** Some metrics will only be sent if the invoking user is root.\n\nAlternatives\n\n* [collectd](http://collectd.org/)\n* [diamond](https://github.com/BrightcoveOS/Diamond)\n* ..\n\n\nipaddr\n------\n\nGet IP addresses easily, either all IPs, all those which are IPv4/IPv6, or\nthose for a device.  Designed primarily for scripting.\n\nExample:\n\n      $ ./ips -4\n      lo 127.0.0.1\n      eth0 80.68.84.102\n      eth0 80.68.84.104\n\nOr to see all IPv6 addreses on eth0:\n\n      $ ipaddr -6 -d eth0\n      eth0 2001:41c8:10b:102::10\n      eth0 fe80::216:3eff:fe08:16a4\n\n**NOTE** Requires compilation via `make build`.\n\nAlternatives:\n\n* `ip -[46] addr  show`\n* `ifconfig -a`\n\n\nmaybe\n-----\n\nIn a similar vein to `true` and `false` the `maybe` command exits with\na status code of zero or one, depending on a random number.\n\nIt can be useful in scripts which need to test-failures, or which benefit\nfrom randomness:\n\nExample:\n\n     maybe \u0026\u0026 echo \"I pass\"\n\n     maybe || echo \"I fail\"\n\n\n\nmulti-ping\n----------\n\nPing a host, regardless of whether it is an IPv6 or IPv4 host.\n\nExample:\n\n     $ multi-ping steve.org.uk\n     Host steve.org.uk - 80.68.85.46 alive\n     Host steve.org.uk - 2001:41c8:125:46:0:0:0:10 alive\n\nAs a convenience you may also specify URIs as arguments, for example:\n\n     $ multi-ping http://steve.org.uk/foo/bar\n     Host steve.org.uk - 80.68.85.46 alive\n     Host steve.org.uk - 2001:41c8:125:46:0:0:0:10 alive\n\nRequirements:\n\n * The `Net::DNS` perl module.\n * The `ping` + `ping6` binaries.\n\n\n\nmysql-slave-check\n-----------------\n\nIf the current host is a MySQL slave this script will test that the\nslave replication is still working.\n\nReplication is regarded as being OK if the following three conditions\nare true:\n\n* The output of \"SHOW SLAVE STATUS\" includes: Slave_IO_Running: Yes\n* The output of \"SHOW SLAVE STATUS\" includes: Slave_SQL_Runing: Yes\n* The slave is less than 24 hours behind the master.\n\nExample:\n\n     # ./mysql-slave-check\n     The replication appears to show an error:\n     ..\n     Master_Host: da-db1\n     Master_User: slave\n     Master_Port: 3306\n     Connect_Retry: 60\n     Master_Log_File: mysql-bin.000124\n     Read_Master_Log_Pos: 65667\n     Relay_Log_File: relay-log.001139\n     Relay_Log_Pos: 27251\n     Relay_Master_Log_File: mysql-bin.000124\n     Slave_IO_Running: No\n     Slave_SQL_Running: No\n     ..\n\nThe script exits silently if all is well, unless you add \"`--verbose`\":\n\n     # ./mysql-slave-check -v\n     The slave is running, successfully.\n     Replication lag: 0 seconds\n\n\nRequirements:\n\n * There must be a file /etc/mysql/debian.cnf with valid \"user=\" and \"password=\" lines.\n\n\n\npyhttpd\n-------\n\nA simple Python HTTP server, which has been updated to allow it to bind\nto arbitrary IP addresses, specifically to allow you to bind to localhost.\n\nExample:\n\n     $ ./pyhttpd 127.0.0.1:8080\n     Serving HTTP on 127.0.0.1 port 8080 ...\n\nor\n\n     $ ./pyhttpd 8080\n     Serving HTTP on 0.0.0.0 port 8080 ...\n\n\n\nrandpass\n--------\n\nGenerate a single random password via `/dev/urandom`.\n\nExample:\n\n      $ ./randpass\n      cT3j7Zp6\n      $ ./randpass -n 10\n      ulHrNvYLaa\n      $ ./randpass -n 20 -f\n      oe[d7+e.{Uw=L'RO~[]{\n\n(Adding \"-f\" uses the full alphabet of possible symbols, otherwise only\nalpha-numeric values are shown.  \"-n\" sets the length of the generated\npassword.)\n\nExisting alternatives:\n\n* apg\n* gpw\n* pwgen\n* ...\n\n\n\nsince\n-----\n\nShow the new output since previously reading a file.  This is useful for\nkeeping track of logfile updates.\n\nExample:\n\n       $ ./since /var/log/messages \u003e/dev/null\n       $ logger \"testing the log\"\n       $ ./since /var/log/messages\n       Apr 20 11:24:37 precious skx: testing the log\n\nExisting alternatives:\n\n* logtail\n\n\n\nssh-auth-types\n--------------\n\nShow the authentication types presented by a remote SSH server.\n\nExample:\n\n     $ ./ssh-auth-types precious\n     publickey password\n\n     $ ./ssh-auth-types ssh.example.com\n     publickey\n\n\n\nssh-test\n--------\n\nTest whether `ssh` connections to a list of hosts will succeed, by testing\neach in order.\n\nExample:\n\n     $ ./ssh-test host.list.txt\n     ssh.steve.org.uk    ... OK\n     www.steve.org.uk    ... OK\n     foo.example.com:222 ... OK\n\n     $ cat host.list.txt\n     ssh.steve.org.uk\n     www.steve.org.uk\n     foo.example.com:222\n\nThe format of the input-file is:\n\n    [user@]hostname1[:port]\n    [user@]hostname2[:port]\n    ..\n\n\nsplay\n-----\n\nSleep for a random amount of time, limited by the given max value.  (Default\nis 5 minutes).\n\nExample:\n\n      $ ./splay -v\n      Sleeping for 77 seconds from max splay-time of 300 seconds\n\n      $ ./splay -v -m 20\n      Sleeping for 7 seconds from max splay-time of 20 seconds\n\nExisting alternatives:\n\n* [desync](https://debathena.mit.edu/trac/browser/trunk/athena/bin/desync/)\n\n\n\nssl-expiry-date\n----------------\n\nReport the date, and number of days, until the given SSL certificate\nexpires.  Multiple domain-names may be accepted and each is tested\nin turn.\n\nThe default output is \"noisy\", but you may add \"-d\" to simplify this\nto the domain-name and the number of days remaining on the certificate.\n\n\nExample:\n\n      ./ssl-expiry-date  bbc.co.uk\n      bbc.co.uk\n          Expires: Sep 18 13:50:57 2016 GMT\n          Days: 266\n\n      ./ssl-expiry-date -d bbc.co.uk steve.org.uk\n      bbc.co.uk: 266\n      steve.org.uk: 82\n\n\n\n\ntimeout\n-------\n\nTimeout allows you to run a command which will be killed after the\ngiven number of seconds.\n\nExample:\n\n        # Kill the command after 63 seconds.\n        ./timeout -t 63 top\n\n        # Kill the command after two minutes, five seconds.\n        ./timeout -t 2:5 top\n\n        # Kill the command after three hours, five minutes, and seven seconds\n        ./timeout -t 3:5:7 top\n\n\n\nuntil-success\n-------------\n\nRepeat the specific command until it succeeds - run at least once\nalways.\n\nExample:\n\n         ./until-success ssh example.com -l root -i ~/.ssh/example.com.key\n\nTrivial (ba)sh alternatives:\n\n* while true ; do $cmd; done\n* watch -n 2 $cmd\n\n\n\nwhen-up\n-------\n\nWaits until a given host is online, determined by ping, until executing a given command.\n\nExample:\n\n     $ ./when-up 1.2.3.4 ssh user@1.2.3.4\n     Waiting for 1.2.3.4 to come online...\n     Last login: Sat Dec 28 23:25:01 2013 from 5.6.7.8\n     user@1.2.3.4:~#\n\nAlternatives:\n\n* `until-success ping -c 1 1.2.3.4; ssh user@1.2.3.4`\n\n\n\nuntil-error\n-------------\n\nRepeat the specific command until it fails - run at least once\nalways.\n\nExample:\n\n         ./until-error ssh example.com -l root -i ~/.ssh/example.com.key\n\nTrivial (ba)sh alternatives:\n\n* while true ; do $cmd; done\n* watch -n 2 $cmd\n\n\n\nwhen-down\n-------\n\nWaits until a given host is down\n\nExample:\n\n     $ ./when-down 1.2.3.4 echo \"down\"\n     Waiting for 1.2.3.4 to get down...\n     down\n\nAlternatives:\n\n* `until-error ping -c 1 -W 1 1.2.3.4; echo \"down\"`\n\n\n\nwhich-shell\n-----------\n\nIdentify the shell we're running under.\n\nFor example:\n\n     $ which-shell\n     dash\n\nExisting alternatives:\n\n* `ls -l /bin/sh`\n\n\n\nwith-lock\n---------\n\nRun a command, unless an existing copy of that command is already running,\nvia the creation of a temporary lockfile.\n\nFor example:\n\n     with-lock rsync ...\n\nThe lockfile-name is based upon the SHA1 hash of the command to\nbe executed and the current User-ID.\n\nExisting alternatives:\n\n * lckdo - Requires you to build your own lockfile name.\n * flock - Requires you to build your own lockfile name.\n\n\n\nProblems\n--------\n\nPlease report any issue/suggestions via the github repository:\n\n* https://github.com/skx/sysadmin-util\n\n\n\nAuthor\n------\n\nSteve Kemp \u003csteve@steve.org.uk\u003e\n","funding_links":["https://github.com/sponsors/skx","https://steve.fi/donate/"],"categories":["开源类库","Plugins","Perl"],"sub_categories":["未归类","ZSH on Windows","Zinit (née zplugin)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskx%2Fsysadmin-util","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskx%2Fsysadmin-util","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskx%2Fsysadmin-util/lists"}