mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2026-04-03 17:44:07 +02:00
Compare commits
123 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4989445ef4 | ||
|
|
6770892acd | ||
|
|
d4eba8740f | ||
|
|
9f60760560 | ||
|
|
0a8f8ac934 | ||
|
|
6ae24c8244 | ||
|
|
d3679082a8 | ||
|
|
fb08b42dca | ||
|
|
4aeaa9f42a | ||
|
|
5f5693da04 | ||
|
|
5eb0f61727 | ||
|
|
958e998991 | ||
|
|
b78c1509f6 | ||
|
|
ce184d4d57 | ||
|
|
b4c3714ced | ||
|
|
5b7dfa0438 | ||
|
|
391a388476 | ||
|
|
d9c4e2ed4c | ||
|
|
0c42db38b1 | ||
|
|
2f9be8bf33 | ||
|
|
e8c00155e8 | ||
|
|
cc88fdd9ee | ||
|
|
d9de11ef1d | ||
|
|
0ceda97d09 | ||
|
|
d0dec92ba8 | ||
|
|
d420c008d8 | ||
|
|
f0b32db433 | ||
|
|
bc838eda59 | ||
|
|
afe55b6af0 | ||
|
|
dd3a3ac302 | ||
|
|
f9982a7947 | ||
|
|
07c1be9e9a | ||
|
|
f832b88755 | ||
|
|
0fac757efc | ||
|
|
fc15742065 | ||
|
|
6f2466a131 | ||
|
|
4b90e22f0a | ||
|
|
c493568785 | ||
|
|
1cdf004b77 | ||
|
|
a4ea504261 | ||
|
|
4c2c234c3b | ||
|
|
3d4c0f3e89 | ||
|
|
52fad02903 | ||
|
|
9dcabc057c | ||
|
|
db8c1079dd | ||
|
|
8f954673ab | ||
|
|
79522d1c7d | ||
|
|
a18bf03079 | ||
|
|
c02b6b5d82 | ||
|
|
f99b423284 | ||
|
|
d7d9d45d4f | ||
|
|
90065ec0cd | ||
|
|
51157ebb86 | ||
|
|
96d95c79ca | ||
|
|
e5da34c233 | ||
|
|
f09d657f77 | ||
|
|
0f4b0189f5 | ||
|
|
4666042abb | ||
|
|
027d544c2b | ||
|
|
f1967d0138 | ||
|
|
c1d896027d | ||
|
|
5c2d2a6618 | ||
|
|
997b269b0b | ||
|
|
61257e7525 | ||
|
|
53ee2c3631 | ||
|
|
8bfa0bddec | ||
|
|
ad61e6bc81 | ||
|
|
873b5ba8ac | ||
|
|
6ae50054e2 | ||
|
|
22a35f41bf | ||
|
|
961696c963 | ||
|
|
c7b7f1a5dc | ||
|
|
b5a0d650b1 | ||
|
|
573b279464 | ||
|
|
116e07f161 | ||
|
|
964868c8af | ||
|
|
c8dac32df8 | ||
|
|
72a0016bd8 | ||
|
|
2ad3167434 | ||
|
|
ddabfaa05c | ||
|
|
f857523ca7 | ||
|
|
00d53858e8 | ||
|
|
c008167e66 | ||
|
|
102344a041 | ||
|
|
c865298ef3 | ||
|
|
6ac03faf93 | ||
|
|
49c2701743 | ||
|
|
d1a271b08e | ||
|
|
7388ad19b9 | ||
|
|
2e63cb5fad | ||
|
|
e7f14d02b1 | ||
|
|
873771d05a | ||
|
|
d7de122e36 | ||
|
|
4ef0434f53 | ||
|
|
1aa2c99259 | ||
|
|
c2450b27b0 | ||
|
|
14d6d8b84f | ||
|
|
f0e3846c03 | ||
|
|
6ba64f1128 | ||
|
|
13bcdbc6c9 | ||
|
|
cfba62db20 | ||
|
|
18fb69e36e | ||
|
|
474eb0f3fd | ||
|
|
7f47b53370 | ||
|
|
dc2907d3ce | ||
|
|
1af85811e0 | ||
|
|
1c1b19a478 | ||
|
|
66942d64ba | ||
|
|
2fb6ae08d7 | ||
|
|
bf8811e03e | ||
|
|
c8b502c571 | ||
|
|
81c11a975c | ||
|
|
0d370eb403 | ||
|
|
7492c3f1e3 | ||
|
|
515a8a84b7 | ||
|
|
dd6680efb2 | ||
|
|
a7158373cd | ||
|
|
6d50ec7199 | ||
|
|
95dbf98e8e | ||
|
|
d49323e4eb | ||
|
|
08c1e2aec9 | ||
|
|
a2c137df2e | ||
|
|
fe27dcdb8f |
552
README.md
552
README.md
@@ -1,10 +1,9 @@
|
||||
# JC
|
||||
JSON CLI output utility
|
||||
|
||||
`jc` is used to JSONify the output of many standard linux cli tools and file types for easier parsing in scripts. See the **Parsers** section for supported commands.
|
||||
`jc` is used to JSONify the output of many standard linux cli tools and file types for easier parsing in scripts. See the [**Parsers**](#parsers) section for supported commands and file types.
|
||||
|
||||
This allows further command line processing of output with tools like `jq` simply by piping commands:
|
||||
|
||||
```
|
||||
$ ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)'
|
||||
{
|
||||
@@ -17,9 +16,20 @@ $ ls -l /usr/bin | jc --ls | jq '.[] | select(.size > 50000000)'
|
||||
"date": "Aug 14 19:41"
|
||||
}
|
||||
```
|
||||
For more information on the motivations for this project, please see my blog post at https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/.
|
||||
|
||||
The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary instead of JSON:
|
||||
or using the alternative "magic" syntax:
|
||||
```
|
||||
$ jc ls -l /usr/bin | jq '.[] | select(.size > 50000000)'
|
||||
{
|
||||
"filename": "docker",
|
||||
"flags": "-rwxr-xr-x",
|
||||
"links": 1,
|
||||
"owner": "root",
|
||||
"group": "root",
|
||||
"size": 68677120,
|
||||
"date": "Aug 14 19:41"
|
||||
}
|
||||
```
|
||||
The `jc` parsers can also be used as python modules. In this case the output will be a python dictionary, or list of dictionaries, instead of JSON:
|
||||
```
|
||||
>>> import jc.parsers.ls
|
||||
>>>
|
||||
@@ -49,7 +59,11 @@ Two representations of the data are possible. The default representation uses a
|
||||
|
||||
To access the raw, pre-processed JSON, use the `-r` cli option or the `raw=True` function parameter in `parse()`.
|
||||
|
||||
Schemas for each parser can be found in the `docs/parsers` folder.
|
||||
Schemas for each parser can be found in the [`docs/parsers`](https://github.com/kellyjonbrazil/jc/tree/master/docs/parsers) folder.
|
||||
|
||||
Release notes can be found [here](https://blog.kellybrazil.com/category/jc-news/).
|
||||
|
||||
For more information on the motivations for this project, please see my [blog post](https://blog.kellybrazil.com/2019/11/26/bringing-the-unix-philosophy-to-the-21st-century/).
|
||||
|
||||
## Installation
|
||||
```
|
||||
@@ -57,48 +71,60 @@ $ pip3 install --upgrade jc
|
||||
```
|
||||
|
||||
## Usage
|
||||
`jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`.
|
||||
```
|
||||
jc PARSER [OPTIONS]
|
||||
COMMAND | jc PARSER [OPTIONS]
|
||||
```
|
||||
|
||||
`jc` accepts piped input from `STDIN` and outputs a JSON representation of the previous command's output to `STDOUT`. The JSON output can be compact or pretty formatted.
|
||||
Alternatively, the "magic" syntax can be used by prepending `jc` to the command to be converted. Options can be passed to `jc` immediately before the command is given. (Note: command aliases are not supported)
|
||||
```
|
||||
jc [OPTIONS] COMMAND
|
||||
```
|
||||
The JSON output can be compact (default) or pretty formatted with the `-p` option.
|
||||
|
||||
### Parsers
|
||||
- `--arp` enables the `arp` parser
|
||||
- `--crontab` enables the `crontab` file parser
|
||||
- `--arp` enables the `arp` command parser
|
||||
- `--blkid` enables the `blkid` command parser
|
||||
- `--crontab` enables the `crontab` command and file parser
|
||||
- `--crontab-u` enables the `crontab` file parser with user support
|
||||
- `--df` enables the `df` parser
|
||||
- `--dig` enables the `dig` parser
|
||||
- `--du` enables the `du` parser
|
||||
- `--env` enables the `env` parser
|
||||
- `--free` enables the `free` parser
|
||||
- `--csv` enables the CSV file parser
|
||||
- `--df` enables the `df` command parser
|
||||
- `--dig` enables the `dig` command parser
|
||||
- `--du` enables the `du` command parser
|
||||
- `--env` enables the `env` command parser
|
||||
- `--free` enables the `free` command parser
|
||||
- `--fstab` enables the `/etc/fstab` file parser
|
||||
- `--history` enables the `history` parser
|
||||
- `--group` enables the `/etc/group` file parser
|
||||
- `--gshadow` enables the `/etc/gshadow` file parser
|
||||
- `--history` enables the `history` command parser
|
||||
- `--hosts` enables the `/etc/hosts` file parser
|
||||
- `--id` enables the `id` parser
|
||||
- `--ifconfig` enables the `ifconfig` parser
|
||||
- `--id` enables the `id` command parser
|
||||
- `--ifconfig` enables the `ifconfig` command parser
|
||||
- `--ini` enables the `INI` file parser
|
||||
- `--iptables` enables the `iptables` parser
|
||||
- `--jobs` enables the `jobs` parser
|
||||
- `--ls` enables the `ls` parser
|
||||
- `--lsblk` enables the `lsblk` parser
|
||||
- `--lsmod` enables the `lsmod` parser
|
||||
- `--lsof` enables the `lsof` parser
|
||||
- `--mount` enables the `mount` parser
|
||||
- `--netstat` enables the `netstat` parser
|
||||
- `--pip-list` enables the `pip list` parser
|
||||
- `--pip-show` enables the `pip show` parser
|
||||
- `--ps` enables the `ps` parser
|
||||
- `--route` enables the `route` parser
|
||||
- `--ss` enables the `ss` parser
|
||||
- `--stat` enables the `stat` parser
|
||||
- `--systemctl` enables the `systemctl` parser
|
||||
- `--systemctl-lj` enables the `systemctl list-jobs` parser
|
||||
- `--systemctl-ls` enables the `systemctl list-sockets` parser
|
||||
- `--systemctl-luf` enables the `systemctl list-unit-files` parser
|
||||
- `--uname` enables the `uname -a` parser
|
||||
- `--uptime` enables the `uptime` parser
|
||||
- `--w` enables the `w` parser
|
||||
- `--iptables` enables the `iptables` command parser
|
||||
- `--jobs` enables the `jobs` command parser
|
||||
- `--last` enables the `last` and `lastb` command parser
|
||||
- `--ls` enables the `ls` command parser
|
||||
- `--lsblk` enables the `lsblk` command parser
|
||||
- `--lsmod` enables the `lsmod` command parser
|
||||
- `--lsof` enables the `lsof` command parser
|
||||
- `--mount` enables the `mount` command parser
|
||||
- `--netstat` enables the `netstat` command parser
|
||||
- `--passwd` enables the `/etc/passwd` file parser
|
||||
- `--pip-list` enables the `pip list` command parser
|
||||
- `--pip-show` enables the `pip show` command parser
|
||||
- `--ps` enables the `ps` command parser
|
||||
- `--route` enables the `route` command parser
|
||||
- `--shadow` enables the `/etc/shadow` file parser
|
||||
- `--ss` enables the `ss` command parser
|
||||
- `--stat` enables the `stat` command parser
|
||||
- `--systemctl` enables the `systemctl` command parser
|
||||
- `--systemctl-lj` enables the `systemctl list-jobs` command parser
|
||||
- `--systemctl-ls` enables the `systemctl list-sockets` command parser
|
||||
- `--systemctl-luf` enables the `systemctl list-unit-files` command parser
|
||||
- `--uname` enables the `uname -a` command parser
|
||||
- `--uptime` enables the `uptime` command parser
|
||||
- `--w` enables the `w` command parser
|
||||
- `--who` enables the `who` command parser
|
||||
- `--xml` enables the `XML` file parser
|
||||
- `--yaml` enables the `YAML` file parser
|
||||
|
||||
@@ -109,10 +135,36 @@ jc PARSER [OPTIONS]
|
||||
- `-q` quiet mode. Suppresses warning messages
|
||||
- `-r` raw output. Provides a more literal JSON output with all values as text and no additional sematic processing
|
||||
|
||||
## Contributions
|
||||
Feel free to add/improve code or parsers! You can use the [`jc/parsers/foo.py`](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) parser as a template and submit your parser with a pull request.
|
||||
|
||||
## Compatibility
|
||||
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -ap`.
|
||||
|
||||
|
||||
You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
|
||||
|
||||
```
|
||||
$ cat lsof.out | jc --lsof -q
|
||||
```
|
||||
|
||||
Tested on:
|
||||
- Centos 7.7
|
||||
- Ubuntu 18.4
|
||||
- OSX 10.11.6
|
||||
- OSX 10.14.6
|
||||
|
||||
## Acknowledgments
|
||||
- `ifconfig-parser` module from https://github.com/KnightWhoSayNi/ifconfig-parser
|
||||
- `xmltodict` module from https://github.com/martinblech/xmltodict by Martín Blech
|
||||
- `ruamel.yaml` library from https://pypi.org/project/ruamel.yaml by Anthon van der Neut
|
||||
- Parsing code from Conor Heine at https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 adapted for some parsers
|
||||
- Excellent constructive feedback from Ilya Sher (https://github.com/ilyash-b)
|
||||
|
||||
## Examples
|
||||
### arp
|
||||
```
|
||||
$ arp | jc --arp -p
|
||||
$ arp | jc --arp -p # or: jc -p arp
|
||||
[
|
||||
{
|
||||
"address": "gateway",
|
||||
@@ -138,7 +190,7 @@ $ arp | jc --arp -p
|
||||
]
|
||||
```
|
||||
```
|
||||
$ arp -a | jc --arp -p
|
||||
$ arp -a | jc --arp -p # or: jc -p arp -a
|
||||
[
|
||||
{
|
||||
"name": null,
|
||||
@@ -163,9 +215,56 @@ $ arp -a | jc --arp -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### blkid
|
||||
```
|
||||
$ blkid | jc --blkid -p # or: jc -p blkid
|
||||
[
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"uuid": "05d927ab-5875-49e4-ada1-7f46cb32c932",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"type": "LVM2_member"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-root",
|
||||
"uuid": "07d718ff-950c-4e5b-98f0-42a1147c77d9",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-swap",
|
||||
"uuid": "615eb89a-bcbf-46fd-80e3-c483ff5c931f",
|
||||
"type": "swap"
|
||||
}
|
||||
]
|
||||
```
|
||||
```
|
||||
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p # or: sudo jc -p blkid -o udev -ip /dev/sda2
|
||||
[
|
||||
{
|
||||
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_uuid_enc": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_version": "LVM2\x20001",
|
||||
"id_fs_type": "LVM2_member",
|
||||
"id_fs_usage": "raid",
|
||||
"id_iolimit_minimum_io_size": 512,
|
||||
"id_iolimit_physical_sector_size": 512,
|
||||
"id_iolimit_logical_sector_size": 512,
|
||||
"id_part_entry_scheme": "dos",
|
||||
"id_part_entry_type": "0x8e",
|
||||
"id_part_entry_number": 2,
|
||||
"id_part_entry_offset": 2099200,
|
||||
"id_part_entry_size": 39843840,
|
||||
"id_part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
```
|
||||
### crontab
|
||||
```
|
||||
$ cat /etc/crontab | jc --crontab -p
|
||||
$ cat /etc/crontab | jc --crontab -p # or: jc -p crontab -l
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
@@ -310,9 +409,56 @@ $ cat /etc/crontab | jc --crontab-u -p
|
||||
]
|
||||
}
|
||||
```
|
||||
### CSV files
|
||||
```
|
||||
$ cat homes.csv
|
||||
"Sell", "List", "Living", "Rooms", "Beds", "Baths", "Age", "Acres", "Taxes"
|
||||
142, 160, 28, 10, 5, 3, 60, 0.28, 3167
|
||||
175, 180, 18, 8, 4, 1, 12, 0.43, 4033
|
||||
129, 132, 13, 6, 3, 1, 41, 0.33, 1471
|
||||
...
|
||||
|
||||
$ cat homes.csv | jc --csv -p
|
||||
[
|
||||
{
|
||||
"Sell": "142",
|
||||
"List": "160",
|
||||
"Living": "28",
|
||||
"Rooms": "10",
|
||||
"Beds": "5",
|
||||
"Baths": "3",
|
||||
"Age": "60",
|
||||
"Acres": "0.28",
|
||||
"Taxes": "3167"
|
||||
},
|
||||
{
|
||||
"Sell": "175",
|
||||
"List": "180",
|
||||
"Living": "18",
|
||||
"Rooms": "8",
|
||||
"Beds": "4",
|
||||
"Baths": "1",
|
||||
"Age": "12",
|
||||
"Acres": "0.43",
|
||||
"Taxes": "4033"
|
||||
},
|
||||
{
|
||||
"Sell": "129",
|
||||
"List": "132",
|
||||
"Living": "13",
|
||||
"Rooms": "6",
|
||||
"Beds": "3",
|
||||
"Baths": "1",
|
||||
"Age": "41",
|
||||
"Acres": "0.33",
|
||||
"Taxes": "1471"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### df
|
||||
```
|
||||
$ df | jc --df -p
|
||||
$ df | jc --df -p # or: jc -p df
|
||||
[
|
||||
{
|
||||
"filesystem": "devtmpfs",
|
||||
@@ -335,7 +481,7 @@ $ df | jc --df -p
|
||||
```
|
||||
### dig
|
||||
```
|
||||
$ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p
|
||||
$ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p # or: jc -p dig cnn.com www.cnn.com @205.251.194.64
|
||||
[
|
||||
{
|
||||
"id": 5509,
|
||||
@@ -455,7 +601,7 @@ $ dig cnn.com www.cnn.com @205.251.194.64 | jc --dig -p
|
||||
]
|
||||
```
|
||||
```
|
||||
$ dig -x 1.1.1.1 | jc --dig -p
|
||||
$ dig -x 1.1.1.1 | jc --dig -p # or: jc -p dig -x 1.1.1.1
|
||||
[
|
||||
{
|
||||
"id": 50324,
|
||||
@@ -493,7 +639,7 @@ $ dig -x 1.1.1.1 | jc --dig -p
|
||||
```
|
||||
### du
|
||||
```
|
||||
$ du /usr | jc --du -p
|
||||
$ du /usr | jc --du -p # or: jc -p du /usr
|
||||
[
|
||||
{
|
||||
"size": 104608,
|
||||
@@ -524,7 +670,7 @@ $ du /usr | jc --du -p
|
||||
```
|
||||
### env
|
||||
```
|
||||
$ env | jc --env -p
|
||||
$ env | jc --env -p # or: jc -p env
|
||||
[
|
||||
{
|
||||
"name": "XDG_SESSION_ID",
|
||||
@@ -551,7 +697,7 @@ $ env | jc --env -p
|
||||
```
|
||||
### free
|
||||
```
|
||||
$ free | jc --free -p
|
||||
$ free | jc --free -p # or: jc -p free
|
||||
[
|
||||
{
|
||||
"type": "Mem",
|
||||
@@ -600,6 +746,68 @@ $ cat /etc/fstab | jc --fstab -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/group file
|
||||
```
|
||||
$ cat /etc/group | jc --group -p
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": -2,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": -1,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": 0,
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": 29,
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### /etc/gshadow file
|
||||
```
|
||||
$ cat /etc/gshadow | jc --gshadow -p
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### history
|
||||
```
|
||||
$ history | jc --history -p
|
||||
@@ -674,7 +882,7 @@ $ cat /etc/hosts | jc --hosts -p
|
||||
```
|
||||
### id
|
||||
```
|
||||
$ id | jc --id -p
|
||||
$ id | jc --id -p # or: jc -p id
|
||||
{
|
||||
"uid": {
|
||||
"id": 1000,
|
||||
@@ -704,7 +912,7 @@ $ id | jc --id -p
|
||||
```
|
||||
### ifconfig
|
||||
```
|
||||
$ ifconfig | jc --ifconfig -p
|
||||
$ ifconfig | jc --ifconfig -p # or: jc -p ifconfig
|
||||
[
|
||||
{
|
||||
"name": "ens33",
|
||||
@@ -809,7 +1017,7 @@ $ cat example.ini | jc --ini -p
|
||||
```
|
||||
### iptables
|
||||
```
|
||||
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p
|
||||
$ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p # or: sudo jc -p iptables --line-numbers -v -L -t nat
|
||||
[
|
||||
{
|
||||
"chain": "PREROUTING",
|
||||
@@ -870,7 +1078,7 @@ $ sudo iptables --line-numbers -v -L -t nat | jc --iptables -p
|
||||
```
|
||||
### jobs
|
||||
```
|
||||
$ jobs -l | jc --jobs -p
|
||||
$ jobs -l | jc --jobs -p # or: jc -p jobs
|
||||
[
|
||||
{
|
||||
"job_number": 1,
|
||||
@@ -900,9 +1108,39 @@ $ jobs -l | jc --jobs -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### last and lastb
|
||||
```
|
||||
$ last | jc --last -p # or: jc -p last
|
||||
[
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttys002",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still logged in"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### ls
|
||||
```
|
||||
$ ls -l /usr/bin | jc --ls -p
|
||||
$ ls -l /usr/bin | jc --ls -p # or: jc -p ls -l /usr/bin
|
||||
[
|
||||
{
|
||||
"filename": "apropos",
|
||||
@@ -937,7 +1175,7 @@ $ ls -l /usr/bin | jc --ls -p
|
||||
```
|
||||
### lsblk
|
||||
```
|
||||
$ lsblk | jc --lsblk -p
|
||||
$ lsblk | jc --lsblk -p # or: jc -p lsblk
|
||||
[
|
||||
{
|
||||
"name": "sda",
|
||||
@@ -962,7 +1200,7 @@ $ lsblk | jc --lsblk -p
|
||||
```
|
||||
### lsmod
|
||||
```
|
||||
$ lsmod | jc --lsmod -p
|
||||
$ lsmod | jc --lsmod -p # or: jc -p lsmod
|
||||
[
|
||||
...
|
||||
{
|
||||
@@ -1009,7 +1247,7 @@ $ lsmod | jc --lsmod -p
|
||||
```
|
||||
### lsof
|
||||
```
|
||||
$ sudo lsof | jc --lsof -p
|
||||
$ sudo lsof | jc --lsof -p # or: sudo jc -p lsof
|
||||
[
|
||||
{
|
||||
"command": "systemd",
|
||||
@@ -1052,7 +1290,7 @@ $ sudo lsof | jc --lsof -p
|
||||
```
|
||||
### mount
|
||||
```
|
||||
$ mount | jc --mount -p
|
||||
$ mount | jc --mount -p # or: jc -p mount
|
||||
[
|
||||
{
|
||||
"filesystem": "sysfs",
|
||||
@@ -1096,7 +1334,7 @@ $ mount | jc --mount -p
|
||||
```
|
||||
### netstat
|
||||
```
|
||||
$ sudo netstat -apee | jc --netstat -p
|
||||
$ sudo netstat -apee | jc --netstat -p # or: sudo jc -p netstat -apee
|
||||
[
|
||||
{
|
||||
"proto": "tcp",
|
||||
@@ -1246,9 +1484,43 @@ $ sudo netstat -apee | jc --netstat -p
|
||||
...
|
||||
]
|
||||
```
|
||||
### /etc/passwd file
|
||||
```
|
||||
$ cat /etc/passwd | jc --passwd -p
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": -2,
|
||||
"gid": -2,
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": 1,
|
||||
"gid": 1,
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### pip list
|
||||
```
|
||||
$ pip list | jc --pip-list -p
|
||||
$ pip list | jc --pip-list -p # or: jc -p pip list # or: jc -p pip3 list
|
||||
[
|
||||
{
|
||||
"package": "ansible",
|
||||
@@ -1268,7 +1540,7 @@ $ pip list | jc --pip-list -p
|
||||
```
|
||||
### pip show
|
||||
```
|
||||
$ pip show wrapt wheel | jc --pip-show -p
|
||||
$ pip show wrapt wheel | jc --pip-show -p # or: jc -p pip show wrapt wheel # or: jc -p pip3 show wrapt wheel
|
||||
[
|
||||
{
|
||||
"name": "wrapt",
|
||||
@@ -1298,7 +1570,7 @@ $ pip show wrapt wheel | jc --pip-show -p
|
||||
```
|
||||
### ps
|
||||
```
|
||||
$ ps -ef | jc --ps -p
|
||||
$ ps -ef | jc --ps -p # or: jc -p ps -ef
|
||||
[
|
||||
{
|
||||
"uid": "root",
|
||||
@@ -1334,7 +1606,7 @@ $ ps -ef | jc --ps -p
|
||||
]
|
||||
```
|
||||
```
|
||||
$ ps axu | jc --ps -p
|
||||
$ ps axu | jc --ps -p # or: jc -p ps axu
|
||||
[
|
||||
{
|
||||
"user": "root",
|
||||
@@ -1380,7 +1652,7 @@ $ ps axu | jc --ps -p
|
||||
```
|
||||
### route
|
||||
```
|
||||
$ route -ee | jc --route -p
|
||||
$ route -ee | jc --route -p # or: jc -p route -ee
|
||||
[
|
||||
{
|
||||
"destination": "default",
|
||||
@@ -1423,9 +1695,46 @@ $ route -ee | jc --route -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### /etc/shadow file
|
||||
```
|
||||
$ sudo cat /etc/shadow | jc --shadow -p
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
### ss
|
||||
```
|
||||
$ sudo ss -a | jc --ss -p
|
||||
$ sudo ss -a | jc --ss -p # or: sudo jc -p ss -a
|
||||
[
|
||||
{
|
||||
"netid": "nl",
|
||||
@@ -1544,7 +1853,7 @@ $ sudo ss -a | jc --ss -p
|
||||
```
|
||||
### stat
|
||||
```
|
||||
$ stat /bin/* | jc --stat -p
|
||||
$ stat /bin/* | jc --stat -p # or: jc -p stat /bin/*
|
||||
[
|
||||
{
|
||||
"file": "/bin/bash",
|
||||
@@ -1591,7 +1900,7 @@ $ stat /bin/* | jc --stat -p
|
||||
```
|
||||
### systemctl
|
||||
```
|
||||
$ systemctl -a | jc --systemctl -p
|
||||
$ systemctl -a | jc --systemctl -p # or: jc -p systemctl -a
|
||||
[
|
||||
{
|
||||
"unit": "proc-sys-fs-binfmt_misc.automount",
|
||||
@@ -1619,7 +1928,7 @@ $ systemctl -a | jc --systemctl -p
|
||||
```
|
||||
### systemctl list-jobs
|
||||
```
|
||||
$ systemctl list-jobs| jc --systemctl-lj -p
|
||||
$ systemctl list-jobs | jc --systemctl-lj -p # or: jc -p systemctl list-jobs
|
||||
[
|
||||
{
|
||||
"job": 3543,
|
||||
@@ -1643,7 +1952,7 @@ $ systemctl list-jobs| jc --systemctl-lj -p
|
||||
```
|
||||
### systemctl list-sockets
|
||||
```
|
||||
$ systemctl list-sockets | jc --systemctl-ls -p
|
||||
$ systemctl list-sockets | jc --systemctl-ls -p # or: jc -p systemctl list-sockets
|
||||
[
|
||||
{
|
||||
"listen": "/dev/log",
|
||||
@@ -1665,7 +1974,7 @@ $ systemctl list-sockets | jc --systemctl-ls -p
|
||||
```
|
||||
### systemctl list-unit-files
|
||||
```
|
||||
$ systemctl list-unit-files | jc --systemctl-luf -p
|
||||
$ systemctl list-unit-files | jc --systemctl-luf -p # or: jc -p systemctl list-unit-files
|
||||
[
|
||||
{
|
||||
"unit_file": "proc-sys-fs-binfmt_misc.automount",
|
||||
@@ -1684,7 +1993,7 @@ $ systemctl list-unit-files | jc --systemctl-luf -p
|
||||
```
|
||||
### uname -a
|
||||
```
|
||||
$ uname -a | jc --uname -p
|
||||
$ uname -a | jc --uname -p # or: jc -p uname -a
|
||||
{
|
||||
"kernel_name": "Linux",
|
||||
"node_name": "user-ubuntu",
|
||||
@@ -1698,7 +2007,7 @@ $ uname -a | jc --uname -p
|
||||
```
|
||||
### uptime
|
||||
```
|
||||
$ uptime | jc --uptime -p
|
||||
$ uptime | jc --uptime -p # or: jc -p uptime
|
||||
{
|
||||
"time": "11:30:44",
|
||||
"uptime": "1 day, 21:17",
|
||||
@@ -1710,7 +2019,7 @@ $ uptime | jc --uptime -p
|
||||
```
|
||||
### w
|
||||
```
|
||||
$ w | jc --w -p
|
||||
$ w | jc --w -p # or: jc -p w
|
||||
[
|
||||
{
|
||||
"user": "root",
|
||||
@@ -1744,6 +2053,67 @@ $ w | jc --w -p
|
||||
}
|
||||
]
|
||||
```
|
||||
### who
|
||||
```
|
||||
$ who | jc --who -p # or: jc -p who
|
||||
[
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "ttyS0",
|
||||
"time": "2020-03-02 02:52"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"tty": "pts/0",
|
||||
"time": "2020-03-02 05:15",
|
||||
"from": "192.168.71.1"
|
||||
}
|
||||
]
|
||||
```
|
||||
```
|
||||
$ who -a | jc --who -p # or: jc -p who -a
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": 1
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": 105
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": 51217,
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": 41402
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": 15679,
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
```
|
||||
### XML files
|
||||
```
|
||||
$ cat cd_catalog.xml
|
||||
@@ -1792,7 +2162,7 @@ $ cat cd_catalog.xml | jc --xml -p
|
||||
```
|
||||
### YAML files
|
||||
```
|
||||
$ cat istio-mtls-permissive.yaml
|
||||
$ cat istio.yaml
|
||||
apiVersion: "authentication.istio.io/v1alpha1"
|
||||
kind: "Policy"
|
||||
metadata:
|
||||
@@ -1813,7 +2183,7 @@ spec:
|
||||
tls:
|
||||
mode: ISTIO_MUTUAL
|
||||
|
||||
$ cat istio-mtls-permissive.yaml | jc --yaml -p
|
||||
$ cat istio.yaml | jc --yaml -p
|
||||
[
|
||||
{
|
||||
"apiVersion": "authentication.istio.io/v1alpha1",
|
||||
@@ -1847,34 +2217,4 @@ $ cat istio-mtls-permissive.yaml | jc --yaml -p
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
## TODO
|
||||
Future parsers:
|
||||
- /proc files
|
||||
- /sys files
|
||||
|
||||
## Contributions
|
||||
Feel free to add/improve code or parsers! You can use the `jc/parsers/foo.py` parser as a template and submit your parser with a pull request.
|
||||
|
||||
## Compatibility
|
||||
Some parsers like `ls`, `ps`, `dig`, etc. will work on any platform. Other parsers that are platform-specific will generate a warning message if they are used on an unsupported platform. To see all parser information, including compatibility, run `jc -a -p`.
|
||||
|
||||
|
||||
You may still use a parser on an unsupported platform - for example, you may want to parse a file with linux `lsof` output on an OSX laptop. In that case you can suppress the warning message with the `-q` cli option or the `quiet=True` function parameter in `parse()`:
|
||||
|
||||
```
|
||||
$ cat lsof.out | jc --lsof -q
|
||||
```
|
||||
|
||||
Tested on:
|
||||
- Centos 7.7
|
||||
- Ubuntu 18.4
|
||||
- OSX 10.11.6
|
||||
- OSX 10.14.6
|
||||
|
||||
## Acknowledgments
|
||||
- `ifconfig-parser` module from https://github.com/KnightWhoSayNi/ifconfig-parser
|
||||
- `xmltodict` module from https://github.com/martinblech/xmltodict by Martín Blech
|
||||
- `ruamel.yaml` library from https://pypi.org/project/ruamel.yaml by Anthon van der Neut
|
||||
- Parsing code from Conor Heine at https://gist.github.com/cahna/43a1a3ff4d075bcd71f9d7120037a501 adapted for some parsers
|
||||
- Excellent constructive feedback from Ilya Sher (https://github.com/ilyash-b)
|
||||
```
|
||||
@@ -1,7 +1,27 @@
|
||||
jc changelog
|
||||
|
||||
20200303 v1.8.0
|
||||
- Added blkid command parser
|
||||
- Added last and lastb command parser
|
||||
- Added who command parser
|
||||
- Added CSV file parser
|
||||
- Added /etc/passwd file parser
|
||||
- Added /etc/shadow file parser
|
||||
- Added /etc/group file parser
|
||||
- Added /etc/gshadow file parser
|
||||
|
||||
20200227 v1.7.5
|
||||
- Updated ls parser to support filenames with newline characters
|
||||
|
||||
20200219 v1.7.4
|
||||
- Updated ls parser to support multiple directories, globbing, and -R (recursive)
|
||||
|
||||
20200211 v1.7.3
|
||||
- Add alternative 'magic' syntax: e.g. `jc ls -al`
|
||||
- Options can now be condensed (e.g. -prq is equivalant to -p -r -q)
|
||||
|
||||
20200208 v1.7.2
|
||||
- Include test fixtures in wheel
|
||||
- Include test fixtures in wheel and sdist
|
||||
|
||||
20200205 v1.7.1
|
||||
- Add YAML file parser
|
||||
|
||||
@@ -5,14 +5,18 @@ cd jc
|
||||
pydocmd simple jc+ > ../docs/readme.md
|
||||
pydocmd simple utils+ > ../docs/utils.md
|
||||
pydocmd simple jc.parsers.arp+ > ../docs/parsers/arp.md
|
||||
pydocmd simple jc.parsers.blkid+ > ../docs/parsers/blkid.md
|
||||
pydocmd simple jc.parsers.crontab+ > ../docs/parsers/crontab.md
|
||||
pydocmd simple jc.parsers.crontab_u+ > ../docs/parsers/crontab_u.md
|
||||
pydocmd simple jc.parsers.csv+ > ../docs/parsers/csv.md
|
||||
pydocmd simple jc.parsers.df+ > ../docs/parsers/df.md
|
||||
pydocmd simple jc.parsers.dig+ > ../docs/parsers/dig.md
|
||||
pydocmd simple jc.parsers.du+ > ../docs/parsers/du.md
|
||||
pydocmd simple jc.parsers.env+ > ../docs/parsers/env.md
|
||||
pydocmd simple jc.parsers.free+ > ../docs/parsers/free.md
|
||||
pydocmd simple jc.parsers.fstab+ > ../docs/parsers/fstab.md
|
||||
pydocmd simple jc.parsers.group+ > ../docs/parsers/group.md
|
||||
pydocmd simple jc.parsers.gshadow+ > ../docs/parsers/gshadow.md
|
||||
pydocmd simple jc.parsers.history+ > ../docs/parsers/history.md
|
||||
pydocmd simple jc.parsers.hosts+ > ../docs/parsers/hosts.md
|
||||
pydocmd simple jc.parsers.id+ > ../docs/parsers/id.md
|
||||
@@ -20,16 +24,19 @@ pydocmd simple jc.parsers.ifconfig+ > ../docs/parsers/ifconfig.md
|
||||
pydocmd simple jc.parsers.ini+ > ../docs/parsers/ini.md
|
||||
pydocmd simple jc.parsers.iptables+ > ../docs/parsers/iptables.md
|
||||
pydocmd simple jc.parsers.jobs+ > ../docs/parsers/jobs.md
|
||||
pydocmd simple jc.parsers.last+ > ../docs/parsers/last.md
|
||||
pydocmd simple jc.parsers.ls+ > ../docs/parsers/ls.md
|
||||
pydocmd simple jc.parsers.lsblk+ > ../docs/parsers/lsblk.md
|
||||
pydocmd simple jc.parsers.lsmod+ > ../docs/parsers/lsmod.md
|
||||
pydocmd simple jc.parsers.lsof+ > ../docs/parsers/lsof.md
|
||||
pydocmd simple jc.parsers.mount+ > ../docs/parsers/mount.md
|
||||
pydocmd simple jc.parsers.netstat+ > ../docs/parsers/netstat.md
|
||||
pydocmd simple jc.parsers.passwd+ > ../docs/parsers/passwd.md
|
||||
pydocmd simple jc.parsers.pip_list+ > ../docs/parsers/pip_list.md
|
||||
pydocmd simple jc.parsers.pip_show+ > ../docs/parsers/pip_show.md
|
||||
pydocmd simple jc.parsers.ps+ > ../docs/parsers/ps.md
|
||||
pydocmd simple jc.parsers.route+ > ../docs/parsers/route.md
|
||||
pydocmd simple jc.parsers.shadow+ > ../docs/parsers/shadow.md
|
||||
pydocmd simple jc.parsers.ss+ > ../docs/parsers/ss.md
|
||||
pydocmd simple jc.parsers.stat+ > ../docs/parsers/stat.md
|
||||
pydocmd simple jc.parsers.systemctl+ > ../docs/parsers/systemctl.md
|
||||
@@ -39,5 +46,6 @@ pydocmd simple jc.parsers.systemctl_luf+ > ../docs/parsers/systemctl_luf.md
|
||||
pydocmd simple jc.parsers.uname+ > ../docs/parsers/uname.md
|
||||
pydocmd simple jc.parsers.uptime+ > ../docs/parsers/uptime.md
|
||||
pydocmd simple jc.parsers.w+ > ../docs/parsers/w.md
|
||||
pydocmd simple jc.parsers.who+ > ../docs/parsers/who.md
|
||||
pydocmd simple jc.parsers.xml+ > ../docs/parsers/xml.md
|
||||
pydocmd simple jc.parsers.yaml+ > ../docs/parsers/yaml.md
|
||||
|
||||
148
docs/parsers/blkid.md
Normal file
148
docs/parsers/blkid.md
Normal file
@@ -0,0 +1,148 @@
|
||||
# jc.parsers.blkid
|
||||
jc - JSON CLI output utility blkid Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --blkid as the first argument if the piped input is coming from blkid
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ blkid | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"uuid": "05d927ab-5875-49e4-ada1-7f46cb32c932",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"type": "LVM2_member"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-root",
|
||||
"uuid": "07d718ff-950c-4e5b-98f0-42a1147c77d9",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-swap",
|
||||
"uuid": "615eb89a-bcbf-46fd-80e3-c483ff5c931f",
|
||||
"type": "swap"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_uuid_enc": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_version": "LVM2\x20001",
|
||||
"id_fs_type": "LVM2_member",
|
||||
"id_fs_usage": "raid",
|
||||
"id_iolimit_minimum_io_size": 512,
|
||||
"id_iolimit_physical_sector_size": 512,
|
||||
"id_iolimit_logical_sector_size": 512,
|
||||
"id_part_entry_scheme": "dos",
|
||||
"id_part_entry_type": "0x8e",
|
||||
"id_part_entry_number": 2,
|
||||
"id_part_entry_offset": 2099200,
|
||||
"id_part_entry_size": 39843840,
|
||||
"id_part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -ip /dev/sda1 | jc --blkid -p -r
|
||||
[
|
||||
{
|
||||
"devname": "/dev/sda1",
|
||||
"uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932",
|
||||
"type": "xfs",
|
||||
"usage": "filesystem",
|
||||
"minimum_io_size": "512",
|
||||
"physical_sector_size": "512",
|
||||
"logical_sector_size": "512",
|
||||
"part_entry_scheme": "dos",
|
||||
"part_entry_type": "0x83",
|
||||
"part_entry_flags": "0x80",
|
||||
"part_entry_number": "1",
|
||||
"part_entry_offset": "2048",
|
||||
"part_entry_size": "2097152",
|
||||
"part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"device": string,
|
||||
"uuid": string,
|
||||
"type": string,
|
||||
"usage": string,
|
||||
"part_entry_scheme": string,
|
||||
"part_entry_type": string,
|
||||
"part_entry_flags": string,
|
||||
"part_entry_number": integer,
|
||||
"part_entry_offset": integer,
|
||||
"part_entry_size": integer,
|
||||
"part_entry_disk": string,
|
||||
"id_fs_uuid": string,
|
||||
"id_fs_uuid_enc": string,
|
||||
"id_fs_version": string,
|
||||
"id_fs_type": string,
|
||||
"id_fs_usage": string,
|
||||
"id_part_entry_scheme": string,
|
||||
"id_part_entry_type": string,
|
||||
"id_part_entry_flags": string,
|
||||
"id_part_entry_number": integer,
|
||||
"id_part_entry_offset": integer,
|
||||
"id_part_entry_size": integer,
|
||||
"id_iolimit_minimum_io_size": integer,
|
||||
"id_iolimit_physical_sector_size": integer,
|
||||
"id_iolimit_logical_sector_size": integer,
|
||||
"id_part_entry_disk": string,
|
||||
"minimum_io_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"logical_sector_size": integer
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# jc.parsers.crontab
|
||||
jc - JSON CLI output utility crontab file Parser
|
||||
jc - JSON CLI output utility crontab command and file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --crontab as the first argument if the piped input is coming from a crontab file
|
||||
specify --crontab as the first argument if the piped input is coming from crontab -l or a crontab file
|
||||
|
||||
Compatibility:
|
||||
|
||||
@@ -11,7 +11,7 @@ Compatibility:
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/crontab | jc --crontab -p
|
||||
$ crontab -l | jc --crontab -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
|
||||
105
docs/parsers/csv.md
Normal file
105
docs/parsers/csv.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# jc.parsers.csv
|
||||
jc - JSON CLI output utility csv Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --csv as the first argument if the piped input is coming from a csv file.
|
||||
the csv parser will attempt to automatically detect the delimiter character.
|
||||
if the delimiter cannot be detected it will default to comma.
|
||||
the first row of the file must be a header row.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat homes.csv
|
||||
"Sell", "List", "Living", "Rooms", "Beds", "Baths", "Age", "Acres", "Taxes"
|
||||
142, 160, 28, 10, 5, 3, 60, 0.28, 3167
|
||||
175, 180, 18, 8, 4, 1, 12, 0.43, 4033
|
||||
129, 132, 13, 6, 3, 1, 41, 0.33, 1471
|
||||
...
|
||||
|
||||
$ cat homes.csv | jc --csv -p
|
||||
[
|
||||
{
|
||||
"Sell": "142",
|
||||
"List": "160",
|
||||
"Living": "28",
|
||||
"Rooms": "10",
|
||||
"Beds": "5",
|
||||
"Baths": "3",
|
||||
"Age": "60",
|
||||
"Acres": "0.28",
|
||||
"Taxes": "3167"
|
||||
},
|
||||
{
|
||||
"Sell": "175",
|
||||
"List": "180",
|
||||
"Living": "18",
|
||||
"Rooms": "8",
|
||||
"Beds": "4",
|
||||
"Baths": "1",
|
||||
"Age": "12",
|
||||
"Acres": "0.43",
|
||||
"Taxes": "4033"
|
||||
},
|
||||
{
|
||||
"Sell": "129",
|
||||
"List": "132",
|
||||
"Living": "13",
|
||||
"Rooms": "6",
|
||||
"Beds": "3",
|
||||
"Baths": "1",
|
||||
"Age": "41",
|
||||
"Acres": "0.33",
|
||||
"Taxes": "1471"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Each dictionary represents a row in the csv file:
|
||||
|
||||
[
|
||||
{
|
||||
csv file converted to a Dictionary
|
||||
https://docs.python.org/3/library/csv.html
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
141
docs/parsers/group.md
Normal file
141
docs/parsers/group.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# jc.parsers.group
|
||||
jc - JSON CLI output utility /etc/group file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --group as the first argument if the piped input is coming from /etc/group
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/group | jc --group -p
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": -2,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": -1,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": 0,
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": 29,
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/group | jc --group -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": "-2",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": "-1",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": "0",
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": "29",
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"gid": integer,
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
109
docs/parsers/gshadow.md
Normal file
109
docs/parsers/gshadow.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# jc.parsers.gshadow
|
||||
jc - JSON CLI output utility /etc/gshadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --gshadow as the first argument if the piped input is coming from /etc/gshadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"administrators": [
|
||||
string
|
||||
],
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
118
docs/parsers/last.md
Normal file
118
docs/parsers/last.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# jc.parsers.last
|
||||
jc - JSON CLI output utility last Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --last as the first argument if the piped input is coming from last or lastb
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ last | jc --last -p
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still logged in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ last | jc --last -p -r
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still_logged_in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"tty": string,
|
||||
"hostname": string,
|
||||
"login": string,
|
||||
"logout": string,
|
||||
"duration": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
# jc.parsers.ls
|
||||
jc - JSON CLI output utility ls Parser
|
||||
|
||||
Note: The -l or -b option of ls should be used to correctly parse filenames that include newline characters.
|
||||
Since ls does not encode newlines in filenames when outputting to a pipe it will cause jc to see
|
||||
multiple files instead of a single file if -l or -b is not used.
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ls as the first argument if the piped input is coming from ls
|
||||
|
||||
ls options supported:
|
||||
- None
|
||||
- la
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
-lbaR
|
||||
--time-style=full-iso
|
||||
-h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
Compatibility:
|
||||
|
||||
@@ -165,6 +170,7 @@ Returns:
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
|
||||
126
docs/parsers/passwd.md
Normal file
126
docs/parsers/passwd.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# jc.parsers.passwd
|
||||
jc - JSON CLI output utility /etc/passwd file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --passwd as the first argument if the piped input is coming from /etc/passwd
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": -2,
|
||||
"gid": -2,
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": 1,
|
||||
"gid": 1,
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p -r
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": "-2",
|
||||
"gid": "-2",
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": "0",
|
||||
"gid": "0",
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": "1",
|
||||
"gid": "1",
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"uid": integer,
|
||||
"gid": integer,
|
||||
"comment": string,
|
||||
"home": string,
|
||||
"shell": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
133
docs/parsers/shadow.md
Normal file
133
docs/parsers/shadow.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# jc.parsers.shadow
|
||||
jc - JSON CLI output utility /etc/shadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --shadow as the first argument if the piped input is coming from /etc/shadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p -r
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"last_changed": integer,
|
||||
"minimum": integer,
|
||||
"maximum": integer,
|
||||
"warn": integer,
|
||||
"inactive": integer,
|
||||
"expire": integer
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
152
docs/parsers/who.md
Normal file
152
docs/parsers/who.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# jc.parsers.who
|
||||
jc - JSON CLI output utility who Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --who as the first argument if the piped input is coming from who
|
||||
|
||||
accepts any of the following who options (or no options): -aTH
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ who -a | jc --who -p
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": 1
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": 105
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": 51217,
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": 41402
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": 15679,
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
|
||||
$ who -a | jc --who -p -r
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": "1"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": "105"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": "51217",
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": "41402"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": "15679",
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
|
||||
## info
|
||||
```python
|
||||
info(self, /, *args, **kwargs)
|
||||
```
|
||||
|
||||
## process
|
||||
```python
|
||||
process(proc_data)
|
||||
```
|
||||
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"event": string,
|
||||
"writeable_tty": string,
|
||||
"tty": string,
|
||||
"time": string,
|
||||
"idle": string,
|
||||
"pid": integer,
|
||||
"from": string,
|
||||
"comment": string
|
||||
}
|
||||
]
|
||||
|
||||
## parse
|
||||
```python
|
||||
parse(data, raw=False, quiet=False)
|
||||
```
|
||||
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
|
||||
114
jc/cli.py
114
jc/cli.py
@@ -3,6 +3,8 @@
|
||||
JC cli module
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import importlib
|
||||
import textwrap
|
||||
import signal
|
||||
@@ -11,7 +13,7 @@ import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.7.2'
|
||||
version = '1.8.0'
|
||||
description = 'jc cli output JSON conversion tool'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -21,14 +23,18 @@ __version__ = info.version
|
||||
|
||||
parsers = [
|
||||
'arp',
|
||||
'blkid',
|
||||
'crontab',
|
||||
'crontab-u',
|
||||
'csv',
|
||||
'df',
|
||||
'dig',
|
||||
'du',
|
||||
'env',
|
||||
'free',
|
||||
'fstab',
|
||||
'group',
|
||||
'gshadow',
|
||||
'history',
|
||||
'hosts',
|
||||
'id',
|
||||
@@ -36,16 +42,19 @@ parsers = [
|
||||
'ini',
|
||||
'iptables',
|
||||
'jobs',
|
||||
'last',
|
||||
'ls',
|
||||
'lsblk',
|
||||
'lsmod',
|
||||
'lsof',
|
||||
'mount',
|
||||
'netstat',
|
||||
'passwd',
|
||||
'pip-list',
|
||||
'pip-show',
|
||||
'ps',
|
||||
'route',
|
||||
'shadow',
|
||||
'ss',
|
||||
'stat',
|
||||
'systemctl',
|
||||
@@ -55,12 +64,14 @@ parsers = [
|
||||
'uname',
|
||||
'uptime',
|
||||
'w',
|
||||
'who',
|
||||
'xml',
|
||||
'yaml'
|
||||
]
|
||||
|
||||
|
||||
def ctrlc(signum, frame):
|
||||
"""exit with error on SIGINT"""
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -80,12 +91,13 @@ def parser_mod_shortname(parser):
|
||||
|
||||
|
||||
def parser_module(parser):
|
||||
"""import the module just in time and present the module object"""
|
||||
"""import the module just in time and return the module object"""
|
||||
importlib.import_module('jc.parsers.' + parser_mod_shortname(parser))
|
||||
return getattr(jc.parsers, parser_mod_shortname(parser))
|
||||
|
||||
|
||||
def parsers_text(indent=0, pad=0):
|
||||
"""return the argument and description information from each parser"""
|
||||
ptext = ''
|
||||
for parser in parsers:
|
||||
parser_arg = parser_argument(parser)
|
||||
@@ -103,6 +115,7 @@ def parsers_text(indent=0, pad=0):
|
||||
|
||||
|
||||
def about_jc():
|
||||
"""return jc info and the contents of each parser.info as a dictionary"""
|
||||
parser_list = []
|
||||
|
||||
for parser in parsers:
|
||||
@@ -132,12 +145,17 @@ def about_jc():
|
||||
|
||||
|
||||
def helptext(message):
|
||||
"""return the help text with the list of parsers"""
|
||||
parsers_string = parsers_text(indent=12, pad=17)
|
||||
|
||||
helptext_string = f'''
|
||||
jc: {message}
|
||||
|
||||
Usage: jc PARSER [OPTIONS]
|
||||
Usage: COMMAND | jc PARSER [OPTIONS]
|
||||
|
||||
or magic syntax:
|
||||
|
||||
jc [OPTIONS] COMMAND
|
||||
|
||||
Parsers:
|
||||
{parsers_string}
|
||||
@@ -150,6 +168,10 @@ def helptext(message):
|
||||
|
||||
Example:
|
||||
ls -al | jc --ls -p
|
||||
|
||||
or using the magic syntax:
|
||||
|
||||
jc -p ls -al
|
||||
'''
|
||||
print(textwrap.dedent(helptext_string), file=sys.stderr)
|
||||
|
||||
@@ -161,28 +183,102 @@ def json_out(data, pretty=False):
|
||||
print(json.dumps(data))
|
||||
|
||||
|
||||
def magic():
|
||||
"""Parse with magic syntax: jc -p ls -al"""
|
||||
if len(sys.argv) > 1 and not sys.argv[1].startswith('--'):
|
||||
parser_info = about_jc()['parsers']
|
||||
# correctly parse escape characters and spaces with shlex
|
||||
args_given = " ".join(map(shlex.quote, sys.argv[1:])).split()
|
||||
options = []
|
||||
found_parser = None
|
||||
|
||||
# find the options
|
||||
if args_given[0].startswith('-'):
|
||||
p = 0
|
||||
for i, arg in list(enumerate(args_given)):
|
||||
# parser found - use standard syntax
|
||||
if arg.startswith('--'):
|
||||
return
|
||||
# option found - populate option list
|
||||
elif arg.startswith('-'):
|
||||
options.append(args_given.pop(i - p)[1:])
|
||||
p = p + 1
|
||||
# command found if iterator didn't already stop - stop iterating
|
||||
else:
|
||||
break
|
||||
|
||||
# find the command and parser
|
||||
for parser in parser_info:
|
||||
if 'magic_commands' in parser:
|
||||
# first pass for two word commands: e.g. 'pip list'
|
||||
for magic_command in parser['magic_commands']:
|
||||
try:
|
||||
if ' '.join(args_given[0:2]) == magic_command:
|
||||
found_parser = parser['argument']
|
||||
break
|
||||
# No command found - go to next loop (for cases like 'jc -a')
|
||||
except Exception:
|
||||
break
|
||||
|
||||
# second pass for one word commands: e.g. 'ls'
|
||||
if not found_parser:
|
||||
for magic_command in parser['magic_commands']:
|
||||
try:
|
||||
if args_given[0] == magic_command:
|
||||
found_parser = parser['argument']
|
||||
break
|
||||
# No command found - use standard syntax (for cases like 'jc -a')
|
||||
except Exception:
|
||||
return
|
||||
|
||||
# construct a new command line using the standard syntax: COMMAND | jc --PARSER -OPTIONS
|
||||
run_command = ' '.join(args_given)
|
||||
if found_parser:
|
||||
if options:
|
||||
cmd_options = '-' + ''.join(options)
|
||||
else:
|
||||
cmd_options = ''
|
||||
whole_command = ' '.join([run_command, '|', 'jc', found_parser, cmd_options])
|
||||
|
||||
os.system(whole_command)
|
||||
exit()
|
||||
else:
|
||||
helptext(f'parser not found for "{run_command}"')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
# break on ctrl-c keyboard interrupt
|
||||
signal.signal(signal.SIGINT, ctrlc)
|
||||
|
||||
# try magic syntax first: e.g. jc -p ls -al
|
||||
magic()
|
||||
|
||||
options = []
|
||||
debug = False
|
||||
pretty = False
|
||||
quiet = False
|
||||
raw = False
|
||||
|
||||
# options
|
||||
if '-d' in sys.argv:
|
||||
for opt in sys.argv:
|
||||
if opt.startswith('-') and not opt.startswith('--'):
|
||||
for flag in opt[1:]:
|
||||
options.append(flag)
|
||||
|
||||
if 'd' in options:
|
||||
debug = True
|
||||
|
||||
if '-p' in sys.argv:
|
||||
if 'p' in options:
|
||||
pretty = True
|
||||
|
||||
if '-q' in sys.argv:
|
||||
if 'q' in options:
|
||||
quiet = True
|
||||
|
||||
if '-r' in sys.argv:
|
||||
if 'r' in options:
|
||||
raw = True
|
||||
|
||||
if '-a' in sys.argv:
|
||||
if 'a' in options:
|
||||
json_out(about_jc(), pretty=pretty)
|
||||
exit()
|
||||
|
||||
@@ -215,7 +311,7 @@ def main():
|
||||
result = parser.parse(data, raw=raw, quiet=quiet)
|
||||
found = True
|
||||
break
|
||||
except:
|
||||
except Exception:
|
||||
jc.utils.error_message(f'{parser_name} parser could not parse the input data. Did you use the correct parser?\n For details use the -d option.')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@@ -92,12 +92,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'arp parser'
|
||||
description = 'arp command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['arp']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
219
jc/parsers/blkid.py
Normal file
219
jc/parsers/blkid.py
Normal file
@@ -0,0 +1,219 @@
|
||||
"""jc - JSON CLI output utility blkid Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --blkid as the first argument if the piped input is coming from blkid
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux'
|
||||
|
||||
Examples:
|
||||
|
||||
$ blkid | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"device": "/dev/sda1",
|
||||
"uuid": "05d927ab-5875-49e4-ada1-7f46cb32c932",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/sda2",
|
||||
"uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"type": "LVM2_member"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-root",
|
||||
"uuid": "07d718ff-950c-4e5b-98f0-42a1147c77d9",
|
||||
"type": "xfs"
|
||||
},
|
||||
{
|
||||
"device": "/dev/mapper/centos-swap",
|
||||
"uuid": "615eb89a-bcbf-46fd-80e3-c483ff5c931f",
|
||||
"type": "swap"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -o udev -ip /dev/sda2 | jc --blkid -p
|
||||
[
|
||||
{
|
||||
"id_fs_uuid": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_uuid_enc": "3klkIj-w1kk-DkJi-0XBJ-y3i7-i2Ac-vHqWBM",
|
||||
"id_fs_version": "LVM2\\x20001",
|
||||
"id_fs_type": "LVM2_member",
|
||||
"id_fs_usage": "raid",
|
||||
"id_iolimit_minimum_io_size": 512,
|
||||
"id_iolimit_physical_sector_size": 512,
|
||||
"id_iolimit_logical_sector_size": 512,
|
||||
"id_part_entry_scheme": "dos",
|
||||
"id_part_entry_type": "0x8e",
|
||||
"id_part_entry_number": 2,
|
||||
"id_part_entry_offset": 2099200,
|
||||
"id_part_entry_size": 39843840,
|
||||
"id_part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
|
||||
$ sudo blkid -ip /dev/sda1 | jc --blkid -p -r
|
||||
[
|
||||
{
|
||||
"devname": "/dev/sda1",
|
||||
"uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932",
|
||||
"type": "xfs",
|
||||
"usage": "filesystem",
|
||||
"minimum_io_size": "512",
|
||||
"physical_sector_size": "512",
|
||||
"logical_sector_size": "512",
|
||||
"part_entry_scheme": "dos",
|
||||
"part_entry_type": "0x83",
|
||||
"part_entry_flags": "0x80",
|
||||
"part_entry_number": "1",
|
||||
"part_entry_offset": "2048",
|
||||
"part_entry_size": "2097152",
|
||||
"part_entry_disk": "8:0"
|
||||
}
|
||||
]
|
||||
"""
|
||||
import shlex
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'blkid command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['blkid']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"device": string,
|
||||
"uuid": string,
|
||||
"type": string,
|
||||
"usage": string,
|
||||
"part_entry_scheme": string,
|
||||
"part_entry_type": string,
|
||||
"part_entry_flags": string,
|
||||
"part_entry_number": integer,
|
||||
"part_entry_offset": integer,
|
||||
"part_entry_size": integer,
|
||||
"part_entry_disk": string,
|
||||
"id_fs_uuid": string,
|
||||
"id_fs_uuid_enc": string,
|
||||
"id_fs_version": string,
|
||||
"id_fs_type": string,
|
||||
"id_fs_usage": string,
|
||||
"id_part_entry_scheme": string,
|
||||
"id_part_entry_type": string,
|
||||
"id_part_entry_flags": string,
|
||||
"id_part_entry_number": integer,
|
||||
"id_part_entry_offset": integer,
|
||||
"id_part_entry_size": integer,
|
||||
"id_iolimit_minimum_io_size": integer,
|
||||
"id_iolimit_physical_sector_size": integer,
|
||||
"id_iolimit_logical_sector_size": integer,
|
||||
"id_part_entry_disk": string,
|
||||
"minimum_io_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"logical_sector_size": integer
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
if 'devname' in entry:
|
||||
entry['device'] = entry.pop('devname')
|
||||
|
||||
int_list = ['part_entry_number', 'part_entry_offset', 'part_entry_size', 'id_part_entry_number',
|
||||
'id_part_entry_offset', 'id_part_entry_size', 'minimum_io_size', 'physical_sector_size',
|
||||
'logical_sector_size', 'id_iolimit_minimum_io_size', 'id_iolimit_physical_sector_size',
|
||||
'id_iolimit_logical_sector_size']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
|
||||
if data:
|
||||
# if the first field is a device, use normal parsing:
|
||||
if data.split(maxsplit=1)[0][-1] == ':':
|
||||
linedata = data.splitlines()
|
||||
|
||||
for line in linedata:
|
||||
output_line = {}
|
||||
entries = shlex.split(line)
|
||||
output_line['device'] = entries.pop(0)[:-1]
|
||||
|
||||
for entry in entries:
|
||||
key = entry.split('=', maxsplit=1)[0].lower()
|
||||
value = entry.split('=', maxsplit=1)[1]
|
||||
output_line[key] = value
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
# else use key/value per line parsing
|
||||
else:
|
||||
linedata = data.splitlines()
|
||||
output_line = {}
|
||||
for line in linedata:
|
||||
if line == '':
|
||||
if output_line:
|
||||
raw_output.append(output_line)
|
||||
output_line = {}
|
||||
continue
|
||||
continue
|
||||
|
||||
key = line.split('=', maxsplit=1)[0].lower()
|
||||
value = line.split('=', maxsplit=1)[1]
|
||||
output_line[key] = value
|
||||
|
||||
if output_line:
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,8 +1,8 @@
|
||||
"""jc - JSON CLI output utility crontab file Parser
|
||||
"""jc - JSON CLI output utility crontab command and file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --crontab as the first argument if the piped input is coming from a crontab file
|
||||
specify --crontab as the first argument if the piped input is coming from crontab -l or a crontab file
|
||||
|
||||
Compatibility:
|
||||
|
||||
@@ -10,7 +10,7 @@ Compatibility:
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/crontab | jc --crontab -p
|
||||
$ crontab -l | jc --crontab -p
|
||||
{
|
||||
"variables": [
|
||||
{
|
||||
@@ -133,13 +133,14 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'crontab file parser'
|
||||
description = 'crontab command and file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['crontab']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
141
jc/parsers/csv.py
Normal file
141
jc/parsers/csv.py
Normal file
@@ -0,0 +1,141 @@
|
||||
"""jc - JSON CLI output utility csv Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --csv as the first argument if the piped input is coming from a csv file.
|
||||
the csv parser will attempt to automatically detect the delimiter character.
|
||||
if the delimiter cannot be detected it will default to comma.
|
||||
the first row of the file must be a header row.
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat homes.csv
|
||||
"Sell", "List", "Living", "Rooms", "Beds", "Baths", "Age", "Acres", "Taxes"
|
||||
142, 160, 28, 10, 5, 3, 60, 0.28, 3167
|
||||
175, 180, 18, 8, 4, 1, 12, 0.43, 4033
|
||||
129, 132, 13, 6, 3, 1, 41, 0.33, 1471
|
||||
...
|
||||
|
||||
$ cat homes.csv | jc --csv -p
|
||||
[
|
||||
{
|
||||
"Sell": "142",
|
||||
"List": "160",
|
||||
"Living": "28",
|
||||
"Rooms": "10",
|
||||
"Beds": "5",
|
||||
"Baths": "3",
|
||||
"Age": "60",
|
||||
"Acres": "0.28",
|
||||
"Taxes": "3167"
|
||||
},
|
||||
{
|
||||
"Sell": "175",
|
||||
"List": "180",
|
||||
"Living": "18",
|
||||
"Rooms": "8",
|
||||
"Beds": "4",
|
||||
"Baths": "1",
|
||||
"Age": "12",
|
||||
"Acres": "0.43",
|
||||
"Taxes": "4033"
|
||||
},
|
||||
{
|
||||
"Sell": "129",
|
||||
"List": "132",
|
||||
"Living": "13",
|
||||
"Rooms": "6",
|
||||
"Beds": "3",
|
||||
"Baths": "1",
|
||||
"Age": "41",
|
||||
"Acres": "0.33",
|
||||
"Taxes": "1471"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
import csv
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'CSV file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using the python standard csv library'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Each dictionary represents a row in the csv file:
|
||||
|
||||
[
|
||||
{
|
||||
csv file converted to a Dictionary
|
||||
https://docs.python.org/3/library/csv.html
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
# No further processing
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
dialect = None
|
||||
try:
|
||||
dialect = csv.Sniffer().sniff(data[:1024])
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
reader = csv.DictReader(cleandata, dialect=dialect)
|
||||
|
||||
for row in reader:
|
||||
raw_output.append(row)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -74,12 +74,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'df parser'
|
||||
description = 'df command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin']
|
||||
magic_commands = ['df']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -325,12 +325,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'dig parser'
|
||||
description = 'dig command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['dig']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -74,13 +74,14 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'du parser'
|
||||
description = 'du command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['du']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -53,12 +53,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'env parser'
|
||||
description = 'env command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['env']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -21,13 +21,14 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'foo parser'
|
||||
description = 'foo command parser'
|
||||
author = 'John Doe'
|
||||
author_email = 'johndoe@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['foo']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -54,12 +54,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'free parser'
|
||||
description = 'free command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['free']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -71,7 +71,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/fstab file parser'
|
||||
description = 'fstab file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
|
||||
190
jc/parsers/group.py
Normal file
190
jc/parsers/group.py
Normal file
@@ -0,0 +1,190 @@
|
||||
"""jc - JSON CLI output utility /etc/group file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --group as the first argument if the piped input is coming from /etc/group
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/group | jc --group -p
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": -2,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": -1,
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": 0,
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": 29,
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/group | jc --group -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "nobody",
|
||||
"password": "*",
|
||||
"gid": "-2",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "nogroup",
|
||||
"password": "*",
|
||||
"gid": "-1",
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "wheel",
|
||||
"password": "*",
|
||||
"gid": "0",
|
||||
"members": [
|
||||
"root"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "certusers",
|
||||
"password": "*",
|
||||
"gid": "29",
|
||||
"members": [
|
||||
"root",
|
||||
"_jabber",
|
||||
"_postfix",
|
||||
"_cyrus",
|
||||
"_calendar",
|
||||
"_dovecot"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/group file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"gid": integer,
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['gid']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
if entry['members'] == ['']:
|
||||
entry['members'] = []
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['group_name'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['gid'] = fields[2]
|
||||
output_line['members'] = fields[3].split(',')
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
152
jc/parsers/gshadow.py
Normal file
152
jc/parsers/gshadow.py
Normal file
@@ -0,0 +1,152 @@
|
||||
"""jc - JSON CLI output utility /etc/gshadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --gshadow as the first argument if the piped input is coming from /etc/gshadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": []
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/gshadow | jc --gshadow -p -r
|
||||
[
|
||||
{
|
||||
"group_name": "root",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"group_name": "adm",
|
||||
"password": "*",
|
||||
"administrators": [
|
||||
""
|
||||
],
|
||||
"members": [
|
||||
"syslog",
|
||||
"joeuser"
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/gshadow file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"group_name": string,
|
||||
"password": string,
|
||||
"administrators": [
|
||||
string
|
||||
],
|
||||
"members": [
|
||||
string
|
||||
]
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
if entry['administrators'] == ['']:
|
||||
entry['administrators'] = []
|
||||
|
||||
if entry['members'] == ['']:
|
||||
entry['members'] = []
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['group_name'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['administrators'] = fields[2].split(',')
|
||||
output_line['members'] = fields[3].split(',')
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -45,7 +45,7 @@ import jc
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'history parser'
|
||||
description = 'history command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
|
||||
@@ -71,13 +71,14 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'id parser'
|
||||
description = 'id command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['id']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -147,13 +147,14 @@ from ifconfigparser import IfconfigParser
|
||||
|
||||
class info():
|
||||
version = '1.5'
|
||||
description = 'ifconfig parser'
|
||||
description = 'ifconfig command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Using ifconfig-parser package from https://github.com/KnightWhoSayNi/ifconfig-parser'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'aix', 'freebsd', 'darwin']
|
||||
magic_commands = ['ifconfig']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -135,12 +135,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'iptables parser'
|
||||
description = 'iptables command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['iptables']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -78,12 +78,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'jobs parser'
|
||||
description = 'jobs command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['jobs']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
181
jc/parsers/last.py
Normal file
181
jc/parsers/last.py
Normal file
@@ -0,0 +1,181 @@
|
||||
"""jc - JSON CLI output utility last Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --last as the first argument if the piped input is coming from last or lastb
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ last | jc --last -p
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still logged in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": null,
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ last | jc --last -p -r
|
||||
[
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys002",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 14:31",
|
||||
"logout": "still_logged_in"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:38",
|
||||
"logout": "10:38",
|
||||
"duration": "00:00"
|
||||
},
|
||||
{
|
||||
"user": "kbrazil",
|
||||
"tty": "ttys003",
|
||||
"hostname": "-",
|
||||
"login": "Thu Feb 27 10:18",
|
||||
"logout": "10:18",
|
||||
"duration": "00:00"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
"""
|
||||
import re
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'last and lastb command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
magic_commands = ['last', 'lastb']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"tty": string,
|
||||
"hostname": string,
|
||||
"login": string,
|
||||
"logout": string,
|
||||
"duration": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
if 'tty' in entry and entry['tty'] == '~':
|
||||
entry['tty'] = None
|
||||
|
||||
if 'tty' in entry and entry['tty'] == 'system_boot':
|
||||
entry['tty'] = 'system boot'
|
||||
|
||||
if 'hostname' in entry and entry['hostname'] == '-':
|
||||
entry['hostname'] = None
|
||||
|
||||
if 'logout' in entry and entry['logout'] == 'still_logged_in':
|
||||
entry['logout'] = 'still logged in'
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
output_line = {}
|
||||
|
||||
if entry.startswith('wtmp begins ') or entry.startswith('btmp begins '):
|
||||
continue
|
||||
|
||||
entry = entry.replace('system boot', 'system_boot')
|
||||
entry = entry.replace(' still logged in', '- still_logged_in')
|
||||
|
||||
linedata = entry.split()
|
||||
if re.match(r'[MTWFS][ouerha][nedritnu] [JFMASOND][aepuco][nbrynlgptvc]', ' '.join(linedata[2:4])):
|
||||
linedata.insert(2, '-')
|
||||
|
||||
output_line['user'] = linedata[0]
|
||||
output_line['tty'] = linedata[1]
|
||||
output_line['hostname'] = linedata[2]
|
||||
output_line['login'] = ' '.join(linedata[3:7])
|
||||
|
||||
if len(linedata) > 8:
|
||||
output_line['logout'] = linedata[8]
|
||||
|
||||
if len(linedata) > 9:
|
||||
output_line['duration'] = linedata[9].replace('(', '').replace(')', '')
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -1,15 +1,20 @@
|
||||
"""jc - JSON CLI output utility ls Parser
|
||||
|
||||
Note: The -l or -b option of ls should be used to correctly parse filenames that include newline characters.
|
||||
Since ls does not encode newlines in filenames when outputting to a pipe it will cause jc to see
|
||||
multiple files instead of a single file if -l or -b is not used.
|
||||
|
||||
Usage:
|
||||
|
||||
specify --ls as the first argument if the piped input is coming from ls
|
||||
|
||||
ls options supported:
|
||||
- None
|
||||
- la
|
||||
- h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
-lbaR
|
||||
--time-style=full-iso
|
||||
-h file sizes will be available in text form with -r but larger file sizes
|
||||
with human readable suffixes will be converted to Null in default view
|
||||
since the parser attempts to convert this field to an integer.
|
||||
|
||||
Compatibility:
|
||||
|
||||
@@ -144,13 +149,14 @@ import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'ls parser'
|
||||
version = '1.2'
|
||||
description = 'ls command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['ls']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
@@ -173,6 +179,7 @@ def process(proc_data):
|
||||
"filename": string,
|
||||
"flags": string,
|
||||
"links": integer,
|
||||
"parent": string,
|
||||
"owner": string,
|
||||
"group": string,
|
||||
"size": integer,
|
||||
@@ -212,27 +219,58 @@ def parse(data, raw=False, quiet=False):
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
warned = False
|
||||
parent = ''
|
||||
next_is_parent = False
|
||||
new_section = False
|
||||
|
||||
linedata = data.splitlines()
|
||||
|
||||
# Delete first line if it starts with 'total'
|
||||
# Delete first line if it starts with 'total 1234'
|
||||
if linedata:
|
||||
if linedata[0].find('total') == 0:
|
||||
if re.match(r'total [0-9]+', linedata[0]):
|
||||
linedata.pop(0)
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, linedata))
|
||||
# Look for parent line if glob or -R is used
|
||||
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]) \
|
||||
and linedata[0].endswith(':'):
|
||||
parent = linedata.pop(0)[:-1]
|
||||
# Pop following total line
|
||||
linedata.pop(0)
|
||||
|
||||
if cleandata:
|
||||
if linedata:
|
||||
# Check if -l was used to parse extra data
|
||||
if re.match('^[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', cleandata[0]):
|
||||
for entry in cleandata:
|
||||
if re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', linedata[0]):
|
||||
for entry in linedata:
|
||||
output_line = {}
|
||||
|
||||
parsed_line = entry.split(maxsplit=8)
|
||||
|
||||
if not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', entry) \
|
||||
and entry.endswith(':'):
|
||||
parent = entry[:-1]
|
||||
new_section = True
|
||||
|
||||
# fixup to remove trailing \n in previous entry
|
||||
raw_output[-1]['filename'] = raw_output[-1]['filename'][:-1]
|
||||
continue
|
||||
|
||||
if re.match(r'total [0-9]+', entry):
|
||||
new_section = False
|
||||
continue
|
||||
|
||||
# fixup for filenames with newlines
|
||||
if not new_section \
|
||||
and not re.match(r'[-dclpsbDCMnP?]([-r][-w][-xsS]){2}([-r][-w][-xtT])[+]?', entry):
|
||||
raw_output[-1]['filename'] = raw_output[-1]['filename'] + '\n' + entry
|
||||
continue
|
||||
|
||||
# split filenames and links
|
||||
filename_field = parsed_line[8].split(' -> ')
|
||||
if len(parsed_line) == 9:
|
||||
filename_field = parsed_line[8].split(' -> ')
|
||||
else:
|
||||
# in case of filenames starting with a newline character
|
||||
filename_field = ['']
|
||||
|
||||
# create list of dictionaries
|
||||
output_line['filename'] = filename_field[0]
|
||||
@@ -240,6 +278,9 @@ def parse(data, raw=False, quiet=False):
|
||||
if len(filename_field) > 1:
|
||||
output_line['link_to'] = filename_field[1]
|
||||
|
||||
if parent:
|
||||
output_line['parent'] = parent
|
||||
|
||||
output_line['flags'] = parsed_line[0]
|
||||
output_line['links'] = parsed_line[1]
|
||||
output_line['owner'] = parsed_line[2]
|
||||
@@ -248,9 +289,27 @@ def parse(data, raw=False, quiet=False):
|
||||
output_line['date'] = ' '.join(parsed_line[5:8])
|
||||
raw_output.append(output_line)
|
||||
else:
|
||||
for entry in cleandata:
|
||||
for entry in linedata:
|
||||
output_line = {}
|
||||
|
||||
if entry == '':
|
||||
next_is_parent = True
|
||||
continue
|
||||
|
||||
if next_is_parent and entry.endswith(':'):
|
||||
parent = entry[:-1]
|
||||
next_is_parent = False
|
||||
continue
|
||||
|
||||
if not quiet and next_is_parent and not entry.endswith(':') and not warned:
|
||||
jc.utils.warning_message('Newline characters detected. Filenames probably corrupted. Use ls -l or -b instead.')
|
||||
warned = True
|
||||
|
||||
output_line['filename'] = entry
|
||||
|
||||
if parent:
|
||||
output_line['parent'] = parent
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
|
||||
@@ -217,12 +217,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.3'
|
||||
description = 'lsblk parser'
|
||||
description = 'lsblk command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['lsblk']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -108,12 +108,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'lsmod parser'
|
||||
description = 'lsmod command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['lsmod']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -98,12 +98,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'lsof parser'
|
||||
description = 'lsof command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['lsof']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -57,12 +57,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'mount parser'
|
||||
description = 'mount command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin']
|
||||
magic_commands = ['mount']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -314,12 +314,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.2'
|
||||
description = 'netstat parser'
|
||||
description = 'netstat command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['netstat']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
175
jc/parsers/passwd.py
Normal file
175
jc/parsers/passwd.py
Normal file
@@ -0,0 +1,175 @@
|
||||
"""jc - JSON CLI output utility /etc/passwd file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --passwd as the first argument if the piped input is coming from /etc/passwd
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": -2,
|
||||
"gid": -2,
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": 1,
|
||||
"gid": 1,
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ cat /etc/passwd | jc --passwd -p -r
|
||||
[
|
||||
{
|
||||
"username": "nobody",
|
||||
"password": "*",
|
||||
"uid": "-2",
|
||||
"gid": "-2",
|
||||
"comment": "Unprivileged User",
|
||||
"home": "/var/empty",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"uid": "0",
|
||||
"gid": "0",
|
||||
"comment": "System Administrator",
|
||||
"home": "/var/root",
|
||||
"shell": "/bin/sh"
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"uid": "1",
|
||||
"gid": "1",
|
||||
"comment": "System Services",
|
||||
"home": "/var/root",
|
||||
"shell": "/usr/bin/false"
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/passwd file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"uid": integer,
|
||||
"gid": integer,
|
||||
"comment": string,
|
||||
"home": string,
|
||||
"shell": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['uid', 'gid']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['username'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['uid'] = fields[2]
|
||||
output_line['gid'] = fields[3]
|
||||
output_line['comment'] = fields[4]
|
||||
output_line['home'] = fields[5]
|
||||
output_line['shell'] = fields[6]
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -33,12 +33,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'pip list parser'
|
||||
description = 'pip list command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['pip list', 'pip3 list']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -43,12 +43,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'pip show parser'
|
||||
description = 'pip show command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
magic_commands = ['pip show', 'pip3 show']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -178,12 +178,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'ps parser'
|
||||
description = 'ps command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['ps']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -102,12 +102,13 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'route parser'
|
||||
description = 'route command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['route']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
183
jc/parsers/shadow.py
Normal file
183
jc/parsers/shadow.py
Normal file
@@ -0,0 +1,183 @@
|
||||
"""jc - JSON CLI output utility /etc/shadow file Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --shadow as the first argument if the piped input is coming from /etc/shadow
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": 18113,
|
||||
"minimum": 0,
|
||||
"maximum": 99999,
|
||||
"warn": 7,
|
||||
"inactive": null,
|
||||
"expire": null
|
||||
},
|
||||
...
|
||||
]
|
||||
|
||||
$ sudo cat /etc/shadow | jc --shadow -p -r
|
||||
[
|
||||
{
|
||||
"username": "root",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "daemon",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
{
|
||||
"username": "bin",
|
||||
"password": "*",
|
||||
"last_changed": "18113",
|
||||
"minimum": "0",
|
||||
"maximum": "99999",
|
||||
"warn": "7",
|
||||
"inactive": "",
|
||||
"expire": ""
|
||||
},
|
||||
...
|
||||
]
|
||||
"""
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = '/etc/shadow file parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'aix', 'freebsd']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"username": string,
|
||||
"password": string,
|
||||
"last_changed": integer,
|
||||
"minimum": integer,
|
||||
"maximum": integer,
|
||||
"warn": integer,
|
||||
"inactive": integer,
|
||||
"expire": integer
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['last_changed', 'minimum', 'maximum', 'warn', 'inactive', 'expire']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for entry in cleandata:
|
||||
if entry.startswith('#'):
|
||||
continue
|
||||
|
||||
output_line = {}
|
||||
fields = entry.split(':')
|
||||
|
||||
output_line['username'] = fields[0]
|
||||
output_line['password'] = fields[1]
|
||||
output_line['last_changed'] = fields[2]
|
||||
output_line['minimum'] = fields[3]
|
||||
output_line['maximum'] = fields[4]
|
||||
output_line['warn'] = fields[5]
|
||||
output_line['inactive'] = fields[6]
|
||||
output_line['expire'] = fields[7]
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
@@ -252,12 +252,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'ss parser'
|
||||
description = 'ss command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['ss']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -105,12 +105,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'stat parser'
|
||||
description = 'stat command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['stat']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -41,12 +41,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl parser'
|
||||
description = 'systemctl command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -60,12 +60,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl list-jobs parser'
|
||||
description = 'systemctl list-jobs command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl list-jobs']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -35,12 +35,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl list-sockets parser'
|
||||
description = 'systemctl list-sockets command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl list-sockets']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -32,12 +32,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'systemctl list-unit-files parser'
|
||||
description = 'systemctl list-unit-files command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux']
|
||||
magic_commands = ['systemctl list-unit-files']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -31,12 +31,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.1'
|
||||
description = 'uname -a parser'
|
||||
description = 'uname -a command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin']
|
||||
magic_commands = ['uname']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -35,12 +35,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'uptime parser'
|
||||
description = 'uptime command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['uptime']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
@@ -84,12 +84,13 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'w parser'
|
||||
description = 'w command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['w']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
284
jc/parsers/who.py
Normal file
284
jc/parsers/who.py
Normal file
@@ -0,0 +1,284 @@
|
||||
"""jc - JSON CLI output utility who Parser
|
||||
|
||||
Usage:
|
||||
|
||||
specify --who as the first argument if the piped input is coming from who
|
||||
|
||||
accepts any of the following who options (or no options): -aTH
|
||||
|
||||
Compatibility:
|
||||
|
||||
'linux', 'darwin', 'cygwin', 'aix', 'freebsd'
|
||||
|
||||
Examples:
|
||||
|
||||
$ who -a | jc --who -p
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": 1
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": 105
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": 51217,
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": 41402
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": 15679,
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
|
||||
$ who -a | jc --who -p -r
|
||||
[
|
||||
{
|
||||
"event": "reboot",
|
||||
"time": "Feb 7 23:31",
|
||||
"pid": "1"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "-",
|
||||
"tty": "console",
|
||||
"time": "Feb 7 23:32",
|
||||
"idle": "old",
|
||||
"pid": "105"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys000",
|
||||
"time": "Feb 13 16:44",
|
||||
"idle": ".",
|
||||
"pid": "51217",
|
||||
"comment": "term=0 exit=0"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "?",
|
||||
"tty": "ttys003",
|
||||
"time": "Feb 28 08:59",
|
||||
"idle": "01:36",
|
||||
"pid": "41402"
|
||||
},
|
||||
{
|
||||
"user": "joeuser",
|
||||
"writeable_tty": "+",
|
||||
"tty": "ttys004",
|
||||
"time": "Mar 1 16:35",
|
||||
"idle": ".",
|
||||
"pid": "15679",
|
||||
"from": "192.168.1.5"
|
||||
}
|
||||
]
|
||||
"""
|
||||
import re
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
version = '1.0'
|
||||
description = 'who command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
# details = 'enter any other details here'
|
||||
|
||||
# compatible options: linux, darwin, cygwin, win32, aix, freebsd
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'aix', 'freebsd']
|
||||
magic_commands = ['who']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def process(proc_data):
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (dictionary) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Structured data with the following schema:
|
||||
|
||||
[
|
||||
{
|
||||
"user": string,
|
||||
"event": string,
|
||||
"writeable_tty": string,
|
||||
"tty": string,
|
||||
"time": string,
|
||||
"idle": string,
|
||||
"pid": integer,
|
||||
"from": string,
|
||||
"comment": string
|
||||
}
|
||||
]
|
||||
"""
|
||||
for entry in proc_data:
|
||||
int_list = ['pid']
|
||||
for key in int_list:
|
||||
if key in entry:
|
||||
try:
|
||||
key_int = int(entry[key])
|
||||
entry[key] = key_int
|
||||
except (ValueError):
|
||||
entry[key] = None
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
def parse(data, raw=False, quiet=False):
|
||||
"""
|
||||
Main text parsing function
|
||||
|
||||
Parameters:
|
||||
|
||||
data: (string) text data to parse
|
||||
raw: (boolean) output preprocessed JSON if True
|
||||
quiet: (boolean) suppress warning messages if True
|
||||
|
||||
Returns:
|
||||
|
||||
List of dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
if not quiet:
|
||||
jc.utils.compatibility(__name__, info.compatible)
|
||||
|
||||
raw_output = []
|
||||
cleandata = data.splitlines()
|
||||
|
||||
# Clear any blank lines
|
||||
cleandata = list(filter(None, cleandata))
|
||||
|
||||
if cleandata:
|
||||
for line in cleandata:
|
||||
output_line = {}
|
||||
linedata = line.split()
|
||||
|
||||
# clear headers, if they exist
|
||||
if ''.join(linedata[0:3]) == 'NAMELINETIME' \
|
||||
or ''.join(linedata[0:3]) == 'USERLINEWHEN':
|
||||
linedata.pop(0)
|
||||
continue
|
||||
|
||||
# mac reboot line
|
||||
if linedata[0] == 'reboot':
|
||||
output_line['event'] = 'reboot'
|
||||
output_line['time'] = ' '.join(linedata[2:5])
|
||||
output_line['pid'] = linedata[6]
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# linux reboot line
|
||||
if ''.join(linedata[0:2]) == 'systemboot':
|
||||
output_line['event'] = 'reboot'
|
||||
output_line['time'] = ' '.join(linedata[2:4])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# linux login line
|
||||
if linedata[0] == 'LOGIN':
|
||||
output_line['event'] = 'login'
|
||||
output_line['tty'] = linedata[1]
|
||||
output_line['time'] = ' '.join(linedata[2:4])
|
||||
output_line['pid'] = linedata[4]
|
||||
if len(linedata) > 5:
|
||||
output_line['comment'] = ' '.join(linedata[5:])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# linux run-level
|
||||
if linedata[0] == 'run-level':
|
||||
output_line['event'] = ' '.join(linedata[0:2])
|
||||
output_line['time'] = ' '.join(linedata[2:4])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# mac run-level (ignore because not enough useful info)
|
||||
if linedata[1] == 'run-level':
|
||||
continue
|
||||
|
||||
# pts lines with no user information
|
||||
if linedata[0].startswith('pts/'):
|
||||
output_line['tty'] = linedata[0]
|
||||
output_line['time'] = ' '.join(linedata[1:3])
|
||||
output_line['pid'] = linedata[3]
|
||||
output_line['comment'] = ' '.join(linedata[4:])
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# user logins
|
||||
output_line['user'] = linedata.pop(0)
|
||||
|
||||
if linedata[0] in '+-?':
|
||||
output_line['writeable_tty'] = linedata.pop(0)
|
||||
|
||||
output_line['tty'] = linedata.pop(0)
|
||||
|
||||
# mac
|
||||
if re.match(r'[JFMASOND][aepuco][nbrynlgptvc]', linedata[0]):
|
||||
output_line['time'] = ' '.join([linedata.pop(0),
|
||||
linedata.pop(0),
|
||||
linedata.pop(0)])
|
||||
# linux
|
||||
else:
|
||||
output_line['time'] = ' '.join([linedata.pop(0),
|
||||
linedata.pop(0)])
|
||||
|
||||
# if just one more field, then it's the remote IP
|
||||
if len(linedata) == 1:
|
||||
output_line['from'] = linedata[0].replace('(', '').replace(')', '')
|
||||
raw_output.append(output_line)
|
||||
continue
|
||||
|
||||
# extended info: idle
|
||||
if len(linedata) > 0:
|
||||
output_line['idle'] = linedata.pop(0)
|
||||
|
||||
# extended info: pid
|
||||
if len(linedata) > 0:
|
||||
output_line['pid'] = linedata.pop(0)
|
||||
|
||||
# extended info is from
|
||||
if len(linedata) > 0 and linedata[0].startswith('('):
|
||||
output_line['from'] = linedata[0].replace('(', '').replace(')', '')
|
||||
|
||||
# else, extended info is comment
|
||||
elif len(linedata) > 0:
|
||||
output_line['comment'] = ' '.join(linedata)
|
||||
|
||||
raw_output.append(output_line)
|
||||
|
||||
if raw:
|
||||
return raw_output
|
||||
else:
|
||||
return process(raw_output)
|
||||
2
setup.py
2
setup.py
@@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
|
||||
|
||||
setuptools.setup(
|
||||
name='jc',
|
||||
version='1.7.2',
|
||||
version='1.8.0',
|
||||
author='Kelly Brazil',
|
||||
author_email='kellyjonbrazil@gmail.com',
|
||||
description='This tool serializes the output of popular command line tools and filetypes to structured JSON output.',
|
||||
|
||||
1
tests/fixtures/centos-7.7/blkid-ip-multi.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-ip-multi.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "version": "LVM2 001", "type": "LVM2_member", "usage": "raid", "minimum_io_size": 512, "physical_sector_size": 512, "logical_sector_size": 512, "part_entry_scheme": "dos", "part_entry_type": "0x8e", "part_entry_number": 2, "part_entry_offset": 2099200, "part_entry_size": 39843840, "part_entry_disk": "8:0", "device": "/dev/sda2"}, {"uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "type": "xfs", "usage": "filesystem", "minimum_io_size": 512, "physical_sector_size": 512, "logical_sector_size": 512, "part_entry_scheme": "dos", "part_entry_type": "0x83", "part_entry_flags": "0x80", "part_entry_number": 1, "part_entry_offset": 2048, "part_entry_size": 2097152, "part_entry_disk": "8:0", "device": "/dev/sda1"}]
|
||||
29
tests/fixtures/centos-7.7/blkid-ip-multi.out
vendored
Normal file
29
tests/fixtures/centos-7.7/blkid-ip-multi.out
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
DEVNAME=/dev/sda2
|
||||
UUID=3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM
|
||||
VERSION=LVM2 001
|
||||
TYPE=LVM2_member
|
||||
USAGE=raid
|
||||
MINIMUM_IO_SIZE=512
|
||||
PHYSICAL_SECTOR_SIZE=512
|
||||
LOGICAL_SECTOR_SIZE=512
|
||||
PART_ENTRY_SCHEME=dos
|
||||
PART_ENTRY_TYPE=0x8e
|
||||
PART_ENTRY_NUMBER=2
|
||||
PART_ENTRY_OFFSET=2099200
|
||||
PART_ENTRY_SIZE=39843840
|
||||
PART_ENTRY_DISK=8:0
|
||||
|
||||
DEVNAME=/dev/sda1
|
||||
UUID=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
TYPE=xfs
|
||||
USAGE=filesystem
|
||||
MINIMUM_IO_SIZE=512
|
||||
PHYSICAL_SECTOR_SIZE=512
|
||||
LOGICAL_SECTOR_SIZE=512
|
||||
PART_ENTRY_SCHEME=dos
|
||||
PART_ENTRY_TYPE=0x83
|
||||
PART_ENTRY_FLAGS=0x80
|
||||
PART_ENTRY_NUMBER=1
|
||||
PART_ENTRY_OFFSET=2048
|
||||
PART_ENTRY_SIZE=2097152
|
||||
PART_ENTRY_DISK=8:0
|
||||
1
tests/fixtures/centos-7.7/blkid-ip-udev-multi.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-ip-udev-multi.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"id_fs_uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "id_fs_uuid_enc": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "id_fs_version": "LVM2\\x20001", "id_fs_type": "LVM2_member", "id_fs_usage": "raid", "id_iolimit_minimum_io_size": 512, "id_iolimit_physical_sector_size": 512, "id_iolimit_logical_sector_size": 512, "id_part_entry_scheme": "dos", "id_part_entry_type": "0x8e", "id_part_entry_number": 2, "id_part_entry_offset": 2099200, "id_part_entry_size": 39843840, "id_part_entry_disk": "8:0"}, {"id_fs_uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_uuid_enc": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_type": "xfs", "id_fs_usage": "filesystem", "id_iolimit_minimum_io_size": 512, "id_iolimit_physical_sector_size": 512, "id_iolimit_logical_sector_size": 512, "id_part_entry_scheme": "dos", "id_part_entry_type": "0x83", "id_part_entry_flags": "0x80", "id_part_entry_number": 1, "id_part_entry_offset": 2048, "id_part_entry_size": 2097152, "id_part_entry_disk": "8:0"}]
|
||||
29
tests/fixtures/centos-7.7/blkid-ip-udev-multi.out
vendored
Normal file
29
tests/fixtures/centos-7.7/blkid-ip-udev-multi.out
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
ID_FS_UUID=3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM
|
||||
ID_FS_UUID_ENC=3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM
|
||||
ID_FS_VERSION=LVM2\x20001
|
||||
ID_FS_TYPE=LVM2_member
|
||||
ID_FS_USAGE=raid
|
||||
ID_IOLIMIT_MINIMUM_IO_SIZE=512
|
||||
ID_IOLIMIT_PHYSICAL_SECTOR_SIZE=512
|
||||
ID_IOLIMIT_LOGICAL_SECTOR_SIZE=512
|
||||
ID_PART_ENTRY_SCHEME=dos
|
||||
ID_PART_ENTRY_TYPE=0x8e
|
||||
ID_PART_ENTRY_NUMBER=2
|
||||
ID_PART_ENTRY_OFFSET=2099200
|
||||
ID_PART_ENTRY_SIZE=39843840
|
||||
ID_PART_ENTRY_DISK=8:0
|
||||
|
||||
ID_FS_UUID=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_UUID_ENC=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_TYPE=xfs
|
||||
ID_FS_USAGE=filesystem
|
||||
ID_IOLIMIT_MINIMUM_IO_SIZE=512
|
||||
ID_IOLIMIT_PHYSICAL_SECTOR_SIZE=512
|
||||
ID_IOLIMIT_LOGICAL_SECTOR_SIZE=512
|
||||
ID_PART_ENTRY_SCHEME=dos
|
||||
ID_PART_ENTRY_TYPE=0x83
|
||||
ID_PART_ENTRY_FLAGS=0x80
|
||||
ID_PART_ENTRY_NUMBER=1
|
||||
ID_PART_ENTRY_OFFSET=2048
|
||||
ID_PART_ENTRY_SIZE=2097152
|
||||
ID_PART_ENTRY_DISK=8:0
|
||||
1
tests/fixtures/centos-7.7/blkid-ip-udev.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-ip-udev.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"id_fs_uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_uuid_enc": "05d927bb-5875-49e3-ada1-7f46cb31c932", "id_fs_type": "xfs", "id_fs_usage": "filesystem", "id_iolimit_minimum_io_size": 512, "id_iolimit_physical_sector_size": 512, "id_iolimit_logical_sector_size": 512, "id_part_entry_scheme": "dos", "id_part_entry_type": "0x83", "id_part_entry_flags": "0x80", "id_part_entry_number": 1, "id_part_entry_offset": 2048, "id_part_entry_size": 2097152, "id_part_entry_disk": "8:0"}]
|
||||
14
tests/fixtures/centos-7.7/blkid-ip-udev.out
vendored
Normal file
14
tests/fixtures/centos-7.7/blkid-ip-udev.out
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
ID_FS_UUID=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_UUID_ENC=05d927bb-5875-49e3-ada1-7f46cb31c932
|
||||
ID_FS_TYPE=xfs
|
||||
ID_FS_USAGE=filesystem
|
||||
ID_IOLIMIT_MINIMUM_IO_SIZE=512
|
||||
ID_IOLIMIT_PHYSICAL_SECTOR_SIZE=512
|
||||
ID_IOLIMIT_LOGICAL_SECTOR_SIZE=512
|
||||
ID_PART_ENTRY_SCHEME=dos
|
||||
ID_PART_ENTRY_TYPE=0x83
|
||||
ID_PART_ENTRY_FLAGS=0x80
|
||||
ID_PART_ENTRY_NUMBER=1
|
||||
ID_PART_ENTRY_OFFSET=2048
|
||||
ID_PART_ENTRY_SIZE=2097152
|
||||
ID_PART_ENTRY_DISK=8:0
|
||||
1
tests/fixtures/centos-7.7/blkid-sda2.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-sda2.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"device": "/dev/sda2", "uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "type": "LVM2_member"}]
|
||||
1
tests/fixtures/centos-7.7/blkid-sda2.out
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid-sda2.out
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/dev/sda2: UUID="3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM" TYPE="LVM2_member"
|
||||
1
tests/fixtures/centos-7.7/blkid.json
vendored
Normal file
1
tests/fixtures/centos-7.7/blkid.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"device": "/dev/sda1", "uuid": "05d927bb-5875-49e3-ada1-7f46cb31c932", "type": "xfs"}, {"device": "/dev/sda2", "uuid": "3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM", "type": "LVM2_member"}, {"device": "/dev/mapper/centos-root", "uuid": "07d718ef-950c-4e5b-98e0-42a1147b77d9", "type": "xfs"}, {"device": "/dev/mapper/centos-swap", "uuid": "615eb89d-bcbf-46ad-80e3-c483ef5c931f", "type": "swap"}]
|
||||
4
tests/fixtures/centos-7.7/blkid.out
vendored
Normal file
4
tests/fixtures/centos-7.7/blkid.out
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/dev/sda1: UUID="05d927bb-5875-49e3-ada1-7f46cb31c932" TYPE="xfs"
|
||||
/dev/sda2: UUID="3klkIj-w1qk-DkJi-0XBJ-y3o7-i2Ac-vHqWBM" TYPE="LVM2_member"
|
||||
/dev/mapper/centos-root: UUID="07d718ef-950c-4e5b-98e0-42a1147b77d9" TYPE="xfs"
|
||||
/dev/mapper/centos-swap: UUID="615eb89d-bcbf-46ad-80e3-c483ef5c931f" TYPE="swap"
|
||||
1
tests/fixtures/centos-7.7/group.json
vendored
Normal file
1
tests/fixtures/centos-7.7/group.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"group_name": "root", "password": "x", "gid": 0, "members": []}, {"group_name": "bin", "password": "x", "gid": 1, "members": []}, {"group_name": "daemon", "password": "x", "gid": 2, "members": []}, {"group_name": "sys", "password": "x", "gid": 3, "members": []}, {"group_name": "adm", "password": "x", "gid": 4, "members": []}, {"group_name": "tty", "password": "x", "gid": 5, "members": []}, {"group_name": "disk", "password": "x", "gid": 6, "members": []}, {"group_name": "lp", "password": "x", "gid": 7, "members": []}, {"group_name": "mem", "password": "x", "gid": 8, "members": []}, {"group_name": "kmem", "password": "x", "gid": 9, "members": []}, {"group_name": "wheel", "password": "x", "gid": 10, "members": ["joeuser"]}, {"group_name": "cdrom", "password": "x", "gid": 11, "members": []}, {"group_name": "mail", "password": "x", "gid": 12, "members": ["postfix"]}, {"group_name": "man", "password": "x", "gid": 15, "members": []}, {"group_name": "dialout", "password": "x", "gid": 18, "members": []}, {"group_name": "floppy", "password": "x", "gid": 19, "members": []}, {"group_name": "games", "password": "x", "gid": 20, "members": []}, {"group_name": "tape", "password": "x", "gid": 33, "members": []}, {"group_name": "video", "password": "x", "gid": 39, "members": []}, {"group_name": "ftp", "password": "x", "gid": 50, "members": []}, {"group_name": "lock", "password": "x", "gid": 54, "members": []}, {"group_name": "audio", "password": "x", "gid": 63, "members": []}, {"group_name": "nobody", "password": "x", "gid": 99, "members": []}, {"group_name": "users", "password": "x", "gid": 100, "members": []}, {"group_name": "utmp", "password": "x", "gid": 22, "members": []}, {"group_name": "utempter", "password": "x", "gid": 35, "members": []}, {"group_name": "input", "password": "x", "gid": 999, "members": []}, {"group_name": "systemd-journal", "password": "x", "gid": 190, "members": []}, {"group_name": "systemd-network", "password": "x", "gid": 192, "members": []}, {"group_name": "dbus", "password": "x", "gid": 81, "members": []}, {"group_name": "polkitd", "password": "x", "gid": 998, "members": []}, {"group_name": "ssh_keys", "password": "x", "gid": 997, "members": []}, {"group_name": "sshd", "password": "x", "gid": 74, "members": []}, {"group_name": "postdrop", "password": "x", "gid": 90, "members": []}, {"group_name": "postfix", "password": "x", "gid": 89, "members": []}, {"group_name": "chrony", "password": "x", "gid": 996, "members": []}, {"group_name": "joeuser", "password": "x", "gid": 1000, "members": ["joeuser"]}, {"group_name": "cgred", "password": "x", "gid": 995, "members": []}, {"group_name": "dockerroot", "password": "x", "gid": 994, "members": []}]
|
||||
39
tests/fixtures/centos-7.7/group.out
vendored
Normal file
39
tests/fixtures/centos-7.7/group.out
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
root:x:0:
|
||||
bin:x:1:
|
||||
daemon:x:2:
|
||||
sys:x:3:
|
||||
adm:x:4:
|
||||
tty:x:5:
|
||||
disk:x:6:
|
||||
lp:x:7:
|
||||
mem:x:8:
|
||||
kmem:x:9:
|
||||
wheel:x:10:joeuser
|
||||
cdrom:x:11:
|
||||
mail:x:12:postfix
|
||||
man:x:15:
|
||||
dialout:x:18:
|
||||
floppy:x:19:
|
||||
games:x:20:
|
||||
tape:x:33:
|
||||
video:x:39:
|
||||
ftp:x:50:
|
||||
lock:x:54:
|
||||
audio:x:63:
|
||||
nobody:x:99:
|
||||
users:x:100:
|
||||
utmp:x:22:
|
||||
utempter:x:35:
|
||||
input:x:999:
|
||||
systemd-journal:x:190:
|
||||
systemd-network:x:192:
|
||||
dbus:x:81:
|
||||
polkitd:x:998:
|
||||
ssh_keys:x:997:
|
||||
sshd:x:74:
|
||||
postdrop:x:90:
|
||||
postfix:x:89:
|
||||
chrony:x:996:
|
||||
joeuser:x:1000:joeuser
|
||||
cgred:x:995:
|
||||
dockerroot:x:994:
|
||||
1
tests/fixtures/centos-7.7/gshadow.json
vendored
Normal file
1
tests/fixtures/centos-7.7/gshadow.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"group_name": "root", "password": "", "administrators": [], "members": []}, {"group_name": "bin", "password": "", "administrators": [], "members": []}, {"group_name": "daemon", "password": "", "administrators": [], "members": []}, {"group_name": "sys", "password": "", "administrators": [], "members": []}, {"group_name": "adm", "password": "", "administrators": [], "members": []}, {"group_name": "tty", "password": "", "administrators": [], "members": []}, {"group_name": "disk", "password": "", "administrators": [], "members": []}, {"group_name": "lp", "password": "", "administrators": [], "members": []}, {"group_name": "mem", "password": "", "administrators": [], "members": []}, {"group_name": "kmem", "password": "", "administrators": [], "members": []}, {"group_name": "wheel", "password": "", "administrators": [], "members": ["joeuser"]}, {"group_name": "cdrom", "password": "", "administrators": [], "members": []}, {"group_name": "mail", "password": "", "administrators": [], "members": ["postfix"]}, {"group_name": "man", "password": "", "administrators": [], "members": []}, {"group_name": "dialout", "password": "", "administrators": [], "members": []}, {"group_name": "floppy", "password": "", "administrators": [], "members": []}, {"group_name": "games", "password": "", "administrators": [], "members": []}, {"group_name": "tape", "password": "", "administrators": [], "members": []}, {"group_name": "video", "password": "", "administrators": [], "members": []}, {"group_name": "ftp", "password": "", "administrators": [], "members": []}, {"group_name": "lock", "password": "", "administrators": [], "members": []}, {"group_name": "audio", "password": "", "administrators": [], "members": []}, {"group_name": "nobody", "password": "", "administrators": [], "members": []}, {"group_name": "users", "password": "", "administrators": [], "members": []}, {"group_name": "utmp", "password": "!", "administrators": [], "members": []}, {"group_name": "utempter", "password": "!", "administrators": [], "members": []}, {"group_name": "input", "password": "!", "administrators": [], "members": []}, {"group_name": "systemd-journal", "password": "!", "administrators": [], "members": []}, {"group_name": "systemd-network", "password": "!", "administrators": [], "members": []}, {"group_name": "dbus", "password": "!", "administrators": [], "members": []}, {"group_name": "polkitd", "password": "!", "administrators": [], "members": []}, {"group_name": "ssh_keys", "password": "!", "administrators": [], "members": []}, {"group_name": "sshd", "password": "!", "administrators": [], "members": []}, {"group_name": "postdrop", "password": "!", "administrators": [], "members": []}, {"group_name": "postfix", "password": "!", "administrators": [], "members": []}, {"group_name": "chrony", "password": "!", "administrators": [], "members": []}, {"group_name": "joeuser", "password": "!!", "administrators": [], "members": ["joeuser"]}, {"group_name": "cgred", "password": "!", "administrators": [], "members": []}, {"group_name": "dockerroot", "password": "!", "administrators": [], "members": []}]
|
||||
39
tests/fixtures/centos-7.7/gshadow.out
vendored
Normal file
39
tests/fixtures/centos-7.7/gshadow.out
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
root:::
|
||||
bin:::
|
||||
daemon:::
|
||||
sys:::
|
||||
adm:::
|
||||
tty:::
|
||||
disk:::
|
||||
lp:::
|
||||
mem:::
|
||||
kmem:::
|
||||
wheel:::joeuser
|
||||
cdrom:::
|
||||
mail:::postfix
|
||||
man:::
|
||||
dialout:::
|
||||
floppy:::
|
||||
games:::
|
||||
tape:::
|
||||
video:::
|
||||
ftp:::
|
||||
lock:::
|
||||
audio:::
|
||||
nobody:::
|
||||
users:::
|
||||
utmp:!::
|
||||
utempter:!::
|
||||
input:!::
|
||||
systemd-journal:!::
|
||||
systemd-network:!::
|
||||
dbus:!::
|
||||
polkitd:!::
|
||||
ssh_keys:!::
|
||||
sshd:!::
|
||||
postdrop:!::
|
||||
postfix:!::
|
||||
chrony:!::
|
||||
joeuser:!!::joeuser
|
||||
cgred:!::
|
||||
dockerroot:!::
|
||||
1
tests/fixtures/centos-7.7/last-w.json
vendored
Normal file
1
tests/fixtures/centos-7.7/last-w.json
vendored
Normal file
File diff suppressed because one or more lines are too long
69
tests/fixtures/centos-7.7/last-w.out
vendored
Normal file
69
tests/fixtures/centos-7.7/last-w.out
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
kbrazil ttyS0 Fri Feb 28 13:49 still logged in
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Feb 28 12:56 - 14:54 (01:58)
|
||||
kbrazil ttyS0 Thu Feb 27 16:01 - crash (20:54)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Thu Feb 27 15:51 - 14:54 (23:02)
|
||||
kbrazil ttyS0 Thu Feb 27 10:50 - crash (05:01)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Wed Feb 26 20:05 - 14:54 (1+18:49)
|
||||
kbrazil ttyS0 Thu Feb 20 14:42 - crash (6+05:23)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Thu Feb 20 14:41 - 14:54 (8+00:12)
|
||||
kbrazil ttyS0 Mon Feb 17 17:48 - crash (2+20:52)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Feb 17 17:48 - 14:54 (10+21:06)
|
||||
kbrazil ttyS0 Thu Feb 13 16:44 - crash (4+01:03)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Thu Feb 13 16:44 - 14:54 (14+22:10)
|
||||
kbrazil ttyS0 Wed Feb 5 14:23 - crash (8+02:20)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Wed Feb 5 11:43 - 14:54 (23+03:11)
|
||||
kbrazil ttyS0 Tue Feb 4 14:28 - crash (21:15)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Tue Feb 4 01:28 - 14:54 (24+13:26)
|
||||
kbrazil ttyS0 Mon Jan 13 17:28 - crash (21+07:59)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Jan 13 16:16 - 14:54 (45+22:38)
|
||||
kbrazil ttyS0 Mon Dec 16 11:15 - crash (28+05:01)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Dec 16 11:14 - 14:54 (74+03:40)
|
||||
kbrazil ttyS0 Wed Dec 4 21:41 - crash (11+13:33)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Wed Dec 4 21:40 - 14:54 (85+17:13)
|
||||
kbrazil pts/1 Sat Nov 16 14:40 - 14:40 (00:00)
|
||||
kbrazil pts/1 Sat Nov 16 14:39 - 14:39 (00:00)
|
||||
kbrazil pts/0 localhost Tue Nov 12 07:19 - crash (22+14:21)
|
||||
kbrazil ttyS0 Tue Nov 12 07:18 - crash (22+14:22)
|
||||
kbrazil pts/0 localhost Sun Nov 10 08:21 - 15:22 (1+07:01)
|
||||
kbrazil ttyS0 Sat Nov 9 10:34 - 07:16 (2+20:42)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Sat Nov 9 10:34 - 14:54 (111+04:20)
|
||||
kbrazil tty1 Fri Nov 8 07:49 - crash (1+02:45)
|
||||
kbrazil pts/0 192.168.71.1 Fri Nov 8 06:29 - crash (1+04:04)
|
||||
kbrazil ttyS0 Fri Nov 8 06:24 - crash (1+04:09)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Nov 8 06:14 - 14:54 (112+08:40)
|
||||
kbrazil tty1 Sun Nov 3 12:20 - crash (4+17:54)
|
||||
kbrazil ttyS0 Sun Nov 3 11:04 - 11:05 (00:01)
|
||||
kbrazil pts/0 192.168.71.1 Sat Nov 2 19:26 - crash (5+11:47)
|
||||
kbrazil ttyS0 Fri Nov 1 15:14 - 11:03 (1+20:49)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Nov 1 15:13 - 14:54 (119+00:41)
|
||||
kbrazil ttyS0 Fri Nov 1 11:16 - 11:36 (00:20)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Nov 1 06:00 - 11:36 (05:36)
|
||||
kbrazil ttyS0 Tue Oct 29 18:17 - crash (2+11:43)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Tue Oct 29 18:16 - 11:36 (2+17:19)
|
||||
kbrazil pts/0 192.168.71.1 Sat Oct 26 09:53 - 15:13 (05:19)
|
||||
kbrazil ttyS0 Fri Oct 25 18:22 - crash (3+23:54)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Oct 25 18:21 - 11:36 (6+17:14)
|
||||
kbrazil ttyS0 Fri Oct 25 17:14 - 18:21 (01:06)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Oct 25 17:13 - 11:36 (6+18:22)
|
||||
kbrazil ttyS0 Fri Oct 25 15:43 - 17:13 (01:29)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Fri Oct 25 13:29 - 17:13 (03:44)
|
||||
kbrazil ttyS0 Mon Oct 21 13:19 - 19:22 (2+06:03)
|
||||
reboot system boot 3.10.0-1062.1.2.el7.x86_64 Mon Oct 21 13:17 - 19:22 (2+06:05)
|
||||
kbrazil ttyS0 Wed Oct 16 03:23 - crash (5+09:54)
|
||||
kbrazil ttyS0 Tue Oct 15 16:49 - 03:23 (10:34)
|
||||
kbrazil ttyS0 Tue Oct 15 10:39 - 16:48 (06:09)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Tue Oct 15 10:39 - 19:22 (8+08:43)
|
||||
kbrazil ttyS0 Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Thu Aug 15 16:00 - 16:05 (00:05)
|
||||
kbrazil ttyS0 Thu Aug 15 14:25 - crash (01:35)
|
||||
reboot system boot 3.10.0-957.27.2.el7.x86_64 Thu Aug 15 14:24 - 16:05 (01:41)
|
||||
kbrazil ttyS0 Thu Aug 15 11:58 - crash (02:25)
|
||||
reboot system boot 3.10.0-957.el7.x86_64 Thu Aug 15 11:58 - 16:05 (04:07)
|
||||
kbrazil ttyS0 Thu Aug 15 11:57 - 11:57 (00:00)
|
||||
reboot system boot 3.10.0-957.el7.x86_64 Thu Aug 15 11:57 - 16:05 (04:08)
|
||||
kbrazil pts/0 192.168.71.1 Thu Aug 15 10:58 - 11:56 (00:58)
|
||||
root tty1 Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
reboot system boot 3.10.0-957.el7.x86_64 Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
|
||||
wtmp begins Thu Aug 15 10:57:06 2019
|
||||
1
tests/fixtures/centos-7.7/last.json
vendored
Normal file
1
tests/fixtures/centos-7.7/last.json
vendored
Normal file
File diff suppressed because one or more lines are too long
69
tests/fixtures/centos-7.7/last.out
vendored
Normal file
69
tests/fixtures/centos-7.7/last.out
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
kbrazil ttyS0 Fri Feb 28 13:49 still logged in
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Feb 28 12:56 - 14:52 (01:56)
|
||||
kbrazil ttyS0 Thu Feb 27 16:01 - crash (20:54)
|
||||
reboot system boot 3.10.0-1062.1.2. Thu Feb 27 15:51 - 14:52 (23:01)
|
||||
kbrazil ttyS0 Thu Feb 27 10:50 - crash (05:01)
|
||||
reboot system boot 3.10.0-1062.1.2. Wed Feb 26 20:05 - 14:52 (1+18:47)
|
||||
kbrazil ttyS0 Thu Feb 20 14:42 - crash (6+05:23)
|
||||
reboot system boot 3.10.0-1062.1.2. Thu Feb 20 14:41 - 14:52 (8+00:11)
|
||||
kbrazil ttyS0 Mon Feb 17 17:48 - crash (2+20:52)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Feb 17 17:48 - 14:52 (10+21:04)
|
||||
kbrazil ttyS0 Thu Feb 13 16:44 - crash (4+01:03)
|
||||
reboot system boot 3.10.0-1062.1.2. Thu Feb 13 16:44 - 14:52 (14+22:08)
|
||||
kbrazil ttyS0 Wed Feb 5 14:23 - crash (8+02:20)
|
||||
reboot system boot 3.10.0-1062.1.2. Wed Feb 5 11:43 - 14:52 (23+03:09)
|
||||
kbrazil ttyS0 Tue Feb 4 14:28 - crash (21:15)
|
||||
reboot system boot 3.10.0-1062.1.2. Tue Feb 4 01:28 - 14:52 (24+13:24)
|
||||
kbrazil ttyS0 Mon Jan 13 17:28 - crash (21+07:59)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Jan 13 16:16 - 14:52 (45+22:36)
|
||||
kbrazil ttyS0 Mon Dec 16 11:15 - crash (28+05:01)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Dec 16 11:14 - 14:52 (74+03:38)
|
||||
kbrazil ttyS0 Wed Dec 4 21:41 - crash (11+13:33)
|
||||
reboot system boot 3.10.0-1062.1.2. Wed Dec 4 21:40 - 14:52 (85+17:12)
|
||||
kbrazil pts/1 Sat Nov 16 14:40 - 14:40 (00:00)
|
||||
kbrazil pts/1 Sat Nov 16 14:39 - 14:39 (00:00)
|
||||
kbrazil pts/0 localhost Tue Nov 12 07:19 - crash (22+14:21)
|
||||
kbrazil ttyS0 Tue Nov 12 07:18 - crash (22+14:22)
|
||||
kbrazil pts/0 localhost Sun Nov 10 08:21 - 15:22 (1+07:01)
|
||||
kbrazil ttyS0 Sat Nov 9 10:34 - 07:16 (2+20:42)
|
||||
reboot system boot 3.10.0-1062.1.2. Sat Nov 9 10:34 - 14:52 (111+04:18)
|
||||
kbrazil tty1 Fri Nov 8 07:49 - crash (1+02:45)
|
||||
kbrazil pts/0 192.168.71.1 Fri Nov 8 06:29 - crash (1+04:04)
|
||||
kbrazil ttyS0 Fri Nov 8 06:24 - crash (1+04:09)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Nov 8 06:14 - 14:52 (112+08:38)
|
||||
kbrazil tty1 Sun Nov 3 12:20 - crash (4+17:54)
|
||||
kbrazil ttyS0 Sun Nov 3 11:04 - 11:05 (00:01)
|
||||
kbrazil pts/0 192.168.71.1 Sat Nov 2 19:26 - crash (5+11:47)
|
||||
kbrazil ttyS0 Fri Nov 1 15:14 - 11:03 (1+20:49)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Nov 1 15:13 - 14:52 (119+00:39)
|
||||
kbrazil ttyS0 Fri Nov 1 11:16 - 11:36 (00:20)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Nov 1 06:00 - 11:36 (05:36)
|
||||
kbrazil ttyS0 Tue Oct 29 18:17 - crash (2+11:43)
|
||||
reboot system boot 3.10.0-1062.1.2. Tue Oct 29 18:16 - 11:36 (2+17:19)
|
||||
kbrazil pts/0 192.168.71.1 Sat Oct 26 09:53 - 15:13 (05:19)
|
||||
kbrazil ttyS0 Fri Oct 25 18:22 - crash (3+23:54)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Oct 25 18:21 - 11:36 (6+17:14)
|
||||
kbrazil ttyS0 Fri Oct 25 17:14 - 18:21 (01:06)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Oct 25 17:13 - 11:36 (6+18:22)
|
||||
kbrazil ttyS0 Fri Oct 25 15:43 - 17:13 (01:29)
|
||||
reboot system boot 3.10.0-1062.1.2. Fri Oct 25 13:29 - 17:13 (03:44)
|
||||
kbrazil ttyS0 Mon Oct 21 13:19 - 19:22 (2+06:03)
|
||||
reboot system boot 3.10.0-1062.1.2. Mon Oct 21 13:17 - 19:22 (2+06:05)
|
||||
kbrazil ttyS0 Wed Oct 16 03:23 - crash (5+09:54)
|
||||
kbrazil ttyS0 Tue Oct 15 16:49 - 03:23 (10:34)
|
||||
kbrazil ttyS0 Tue Oct 15 10:39 - 16:48 (06:09)
|
||||
reboot system boot 3.10.0-957.27.2. Tue Oct 15 10:39 - 19:22 (8+08:43)
|
||||
kbrazil ttyS0 Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2. Thu Aug 15 16:05 - 16:05 (00:00)
|
||||
reboot system boot 3.10.0-957.27.2. Thu Aug 15 16:00 - 16:05 (00:05)
|
||||
kbrazil ttyS0 Thu Aug 15 14:25 - crash (01:35)
|
||||
reboot system boot 3.10.0-957.27.2. Thu Aug 15 14:24 - 16:05 (01:41)
|
||||
kbrazil ttyS0 Thu Aug 15 11:58 - crash (02:25)
|
||||
reboot system boot 3.10.0-957.el7.x Thu Aug 15 11:58 - 16:05 (04:07)
|
||||
kbrazil ttyS0 Thu Aug 15 11:57 - 11:57 (00:00)
|
||||
reboot system boot 3.10.0-957.el7.x Thu Aug 15 11:57 - 16:05 (04:08)
|
||||
kbrazil pts/0 192.168.71.1 Thu Aug 15 10:58 - 11:56 (00:58)
|
||||
root tty1 Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
reboot system boot 3.10.0-957.el7.x Thu Aug 15 10:57 - 11:56 (00:59)
|
||||
|
||||
wtmp begins Thu Aug 15 10:57:06 2019
|
||||
1
tests/fixtures/centos-7.7/lastb.json
vendored
Normal file
1
tests/fixtures/centos-7.7/lastb.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"user": "kbrazil", "tty": "ttyS0", "hostname": null, "login": "Fri Feb 28 13:49", "logout": "13:49", "duration": "00:00"}, {"user": "kbrazil", "tty": "ssh:notty", "hostname": "192.168.71.1", "login": "Thu Feb 27 10:13", "logout": "10:13", "duration": "00:00"}, {"user": "kbrazil", "tty": "ttyS0", "hostname": null, "login": "Thu Feb 20 14:41", "logout": "14:41", "duration": "00:00"}, {"user": "kbrazil", "tty": "ttyS0", "hostname": null, "login": "Mon Feb 17 17:48", "logout": "17:48", "duration": "00:00"}]
|
||||
6
tests/fixtures/centos-7.7/lastb.out
vendored
Normal file
6
tests/fixtures/centos-7.7/lastb.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
kbrazil ttyS0 Fri Feb 28 13:49 - 13:49 (00:00)
|
||||
kbrazil ssh:notty 192.168.71.1 Thu Feb 27 10:13 - 10:13 (00:00)
|
||||
kbrazil ttyS0 Thu Feb 20 14:41 - 14:41 (00:00)
|
||||
kbrazil ttyS0 Mon Feb 17 17:48 - 17:48 (00:00)
|
||||
|
||||
btmp begins Mon Feb 17 17:48:53 2020
|
||||
1
tests/fixtures/centos-7.7/ls-R-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-R-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u", "parent": "."}, {"filename": "systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv", "parent": "."}, {"filename": "systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j", "parent": "."}, {"filename": "tmp.CvALl2jE6u", "parent": "."}, {"filename": "tmp.e7AlxSxY5a", "parent": "."}, {"filename": "tmp.uXm9yegjwj", "parent": "."}, {"filename": "a regular filename", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a combination", "parent": "./lstest"}, {"filename": "of everything", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "a newline inside", "parent": "./lstest"}, {"filename": "this file has", "parent": "./lstest"}, {"filename": "four contiguous newlines inside", "parent": "./lstest"}, {"filename": "this file", "parent": "./lstest"}, {"filename": "has", "parent": "./lstest"}, {"filename": "six", "parent": "./lstest"}, {"filename": "newlines", "parent": "./lstest"}, {"filename": "within", "parent": "./lstest"}, {"filename": "this file starts with four newlines", "parent": "./lstest"}, {"filename": "this file starts with one newline", "parent": "./lstest"}]
|
||||
43
tests/fixtures/centos-7.7/ls-R-newlines.out
vendored
Normal file
43
tests/fixtures/centos-7.7/ls-R-newlines.out
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
.:
|
||||
lstest
|
||||
systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u
|
||||
systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv
|
||||
systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j
|
||||
tmp.CvALl2jE6u
|
||||
tmp.e7AlxSxY5a
|
||||
tmp.uXm9yegjwj
|
||||
|
||||
./lstest:
|
||||
a regular filename
|
||||
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
this file has
|
||||
a newline inside
|
||||
this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ls-R.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-R.json
vendored
Normal file
File diff suppressed because one or more lines are too long
5089
tests/fixtures/centos-7.7/ls-R.out
vendored
Normal file
5089
tests/fixtures/centos-7.7/ls-R.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-alR.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-alR.json
vendored
Normal file
File diff suppressed because one or more lines are too long
4997
tests/fixtures/centos-7.7/ls-alR.out
vendored
Normal file
4997
tests/fixtures/centos-7.7/ls-alR.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-glob.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-glob.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1919
tests/fixtures/centos-7.7/ls-glob.out
vendored
Normal file
1919
tests/fixtures/centos-7.7/ls-glob.out
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
tests/fixtures/centos-7.7/ls-l-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-l-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "a regular filename", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:12"}, {"filename": "\n\nthis file has\na combination\n\n\nof everything\n\n\n\n", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:17"}, {"filename": "this file has\na newline inside", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file has\n\n\n\nfour contiguous newlines inside", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file\nhas\nsix\n\nnewlines\n\nwithin", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:16"}, {"filename": "\n\n\n\nthis file starts with four newlines", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:40"}, {"filename": "\nthis file starts with one newline", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:13"}]
|
||||
34
tests/fixtures/centos-7.7/ls-l-newlines.out
vendored
Normal file
34
tests/fixtures/centos-7.7/ls-l-newlines.out
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
total 0
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:12 a regular filename
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:17
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
a newline inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:16 this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:40
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:13
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ls-lR-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-lR-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "lstest", "parent": ".", "flags": "drwxrwxr-x.", "links": 2, "owner": "kbrazil", "group": "kbrazil", "size": 4096, "date": "Feb 22 00:40"}, {"filename": "systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u", "parent": ".", "flags": "drwx------.", "links": 3, "owner": "root", "group": "root", "size": 17, "date": "Feb 13 16:44"}, {"filename": "systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv", "parent": ".", "flags": "drwx------.", "links": 3, "owner": "root", "group": "root", "size": 17, "date": "Feb 17 17:48"}, {"filename": "systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j", "parent": ".", "flags": "drwx------.", "links": 3, "owner": "root", "group": "root", "size": 17, "date": "Feb 20 14:41"}, {"filename": "tmp.CvALl2jE6u", "parent": ".", "flags": "drwx------.", "links": 2, "owner": "root", "group": "root", "size": 6, "date": "Feb 13 16:44"}, {"filename": "tmp.e7AlxSxY5a", "parent": ".", "flags": "drwx------.", "links": 2, "owner": "root", "group": "root", "size": 6, "date": "Feb 20 14:41"}, {"filename": "tmp.uXm9yegjwj", "parent": ".", "flags": "drwx------.", "links": 2, "owner": "root", "group": "root", "size": 6, "date": "Feb 17 17:48"}, {"filename": "a regular filename", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:12"}, {"filename": "\n\nthis file has\na combination\n\n\nof everything\n\n\n\n", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:17"}, {"filename": "this file has\na newline inside", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file has\n\n\n\nfour contiguous newlines inside", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:14"}, {"filename": "this file\nhas\nsix\n\nnewlines\n\nwithin", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:16"}, {"filename": "\n\n\n\nthis file starts with four newlines", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:40"}, {"filename": "\nthis file starts with one newline", "parent": "./lstest", "flags": "-rw-rw-r--.", "links": 1, "owner": "kbrazil", "group": "kbrazil", "size": 0, "date": "Feb 22 00:13"}]
|
||||
45
tests/fixtures/centos-7.7/ls-lR-newlines.out
vendored
Normal file
45
tests/fixtures/centos-7.7/ls-lR-newlines.out
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
.:
|
||||
total 4
|
||||
drwxrwxr-x. 2 kbrazil kbrazil 4096 Feb 22 00:40 lstest
|
||||
drwx------. 3 root root 17 Feb 13 16:44 systemd-private-016de60725a3426792b93fc9f120b8f0-chronyd.service-oZqq4u
|
||||
drwx------. 3 root root 17 Feb 17 17:48 systemd-private-a30a5a178daa4042b42dfaf5ff9e5f68-chronyd.service-a1tpxv
|
||||
drwx------. 3 root root 17 Feb 20 14:41 systemd-private-af69d7360f3e40cfa947358c0fb5a6f8-chronyd.service-T3MQ4j
|
||||
drwx------. 2 root root 6 Feb 13 16:44 tmp.CvALl2jE6u
|
||||
drwx------. 2 root root 6 Feb 20 14:41 tmp.e7AlxSxY5a
|
||||
drwx------. 2 root root 6 Feb 17 17:48 tmp.uXm9yegjwj
|
||||
|
||||
./lstest:
|
||||
total 0
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:12 a regular filename
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:17
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
a newline inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:14 this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:16 this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:40
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
-rw-rw-r--. 1 kbrazil kbrazil 0 Feb 22 00:13
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/ls-newlines.json
vendored
Normal file
1
tests/fixtures/centos-7.7/ls-newlines.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"filename": "a regular filename"}, {"filename": "this file has"}, {"filename": "a combination"}, {"filename": "of everything"}, {"filename": "this file has"}, {"filename": "a newline inside"}, {"filename": "this file has"}, {"filename": "four contiguous newlines inside"}, {"filename": "this file"}, {"filename": "has"}, {"filename": "six"}, {"filename": "newlines"}, {"filename": "within"}, {"filename": "this file starts with four newlines"}, {"filename": "this file starts with one newline"}]
|
||||
33
tests/fixtures/centos-7.7/ls-newlines.out
vendored
Normal file
33
tests/fixtures/centos-7.7/ls-newlines.out
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
a regular filename
|
||||
|
||||
|
||||
this file has
|
||||
a combination
|
||||
|
||||
|
||||
of everything
|
||||
|
||||
|
||||
|
||||
|
||||
this file has
|
||||
a newline inside
|
||||
this file has
|
||||
|
||||
|
||||
|
||||
four contiguous newlines inside
|
||||
this file
|
||||
has
|
||||
six
|
||||
|
||||
newlines
|
||||
|
||||
within
|
||||
|
||||
|
||||
|
||||
|
||||
this file starts with four newlines
|
||||
|
||||
this file starts with one newline
|
||||
1
tests/fixtures/centos-7.7/passwd.json
vendored
Normal file
1
tests/fixtures/centos-7.7/passwd.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"username": "root", "password": "x", "uid": 0, "gid": 0, "comment": "root", "home": "/root", "shell": "/bin/bash"}, {"username": "bin", "password": "x", "uid": 1, "gid": 1, "comment": "bin", "home": "/bin", "shell": "/sbin/nologin"}, {"username": "daemon", "password": "x", "uid": 2, "gid": 2, "comment": "daemon", "home": "/sbin", "shell": "/sbin/nologin"}, {"username": "adm", "password": "x", "uid": 3, "gid": 4, "comment": "adm", "home": "/var/adm", "shell": "/sbin/nologin"}, {"username": "lp", "password": "x", "uid": 4, "gid": 7, "comment": "lp", "home": "/var/spool/lpd", "shell": "/sbin/nologin"}, {"username": "sync", "password": "x", "uid": 5, "gid": 0, "comment": "sync", "home": "/sbin", "shell": "/bin/sync"}, {"username": "shutdown", "password": "x", "uid": 6, "gid": 0, "comment": "shutdown", "home": "/sbin", "shell": "/sbin/shutdown"}, {"username": "halt", "password": "x", "uid": 7, "gid": 0, "comment": "halt", "home": "/sbin", "shell": "/sbin/halt"}, {"username": "mail", "password": "x", "uid": 8, "gid": 12, "comment": "mail", "home": "/var/spool/mail", "shell": "/sbin/nologin"}, {"username": "operator", "password": "x", "uid": 11, "gid": 0, "comment": "operator", "home": "/root", "shell": "/sbin/nologin"}, {"username": "games", "password": "x", "uid": 12, "gid": 100, "comment": "games", "home": "/usr/games", "shell": "/sbin/nologin"}, {"username": "ftp", "password": "x", "uid": 14, "gid": 50, "comment": "FTP User", "home": "/var/ftp", "shell": "/sbin/nologin"}, {"username": "nobody", "password": "x", "uid": 99, "gid": 99, "comment": "Nobody", "home": "/", "shell": "/sbin/nologin"}, {"username": "systemd-network", "password": "x", "uid": 192, "gid": 192, "comment": "systemd Network Management", "home": "/", "shell": "/sbin/nologin"}, {"username": "dbus", "password": "x", "uid": 81, "gid": 81, "comment": "System message bus", "home": "/", "shell": "/sbin/nologin"}, {"username": "polkitd", "password": "x", "uid": 999, "gid": 998, "comment": "User for polkitd", "home": "/", "shell": "/sbin/nologin"}, {"username": "sshd", "password": "x", "uid": 74, "gid": 74, "comment": "Privilege-separated SSH", "home": "/var/empty/sshd", "shell": "/sbin/nologin"}, {"username": "postfix", "password": "x", "uid": 89, "gid": 89, "comment": "", "home": "/var/spool/postfix", "shell": "/sbin/nologin"}, {"username": "chrony", "password": "x", "uid": 998, "gid": 996, "comment": "", "home": "/var/lib/chrony", "shell": "/sbin/nologin"}, {"username": "joeuser", "password": "x", "uid": 1000, "gid": 1000, "comment": "joeuser", "home": "/home/joeuser", "shell": "/bin/bash"}, {"username": "dockerroot", "password": "x", "uid": 997, "gid": 994, "comment": "Docker User", "home": "/var/lib/docker", "shell": "/sbin/nologin"}]
|
||||
21
tests/fixtures/centos-7.7/passwd.out
vendored
Normal file
21
tests/fixtures/centos-7.7/passwd.out
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
bin:x:1:1:bin:/bin:/sbin/nologin
|
||||
daemon:x:2:2:daemon:/sbin:/sbin/nologin
|
||||
adm:x:3:4:adm:/var/adm:/sbin/nologin
|
||||
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
|
||||
sync:x:5:0:sync:/sbin:/bin/sync
|
||||
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
|
||||
halt:x:7:0:halt:/sbin:/sbin/halt
|
||||
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
|
||||
operator:x:11:0:operator:/root:/sbin/nologin
|
||||
games:x:12:100:games:/usr/games:/sbin/nologin
|
||||
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
|
||||
nobody:x:99:99:Nobody:/:/sbin/nologin
|
||||
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
|
||||
dbus:x:81:81:System message bus:/:/sbin/nologin
|
||||
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
|
||||
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
|
||||
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
|
||||
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
|
||||
joeuser:x:1000:1000:joeuser:/home/joeuser:/bin/bash
|
||||
dockerroot:x:997:994:Docker User:/var/lib/docker:/sbin/nologin
|
||||
1
tests/fixtures/centos-7.7/shadow.json
vendored
Normal file
1
tests/fixtures/centos-7.7/shadow.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"username": "root", "password": "$6$27lBiByDWdiM7lvJ$ulWkJyfKNbqDnrIKPLhUCGanKcS5TdY3ZasKMR/v2dl0mHn0s28LcxTXMqqOV0d6tww0U4gmgYZezgAf/F8Pz.", "last_changed": null, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "bin", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "daemon", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "adm", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "lp", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "sync", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "shutdown", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "halt", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "mail", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "operator", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "games", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "ftp", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "nobody", "password": "*", "last_changed": 17834, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "systemd-network", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "dbus", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "polkitd", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "sshd", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "postfix", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "chrony", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}, {"username": "joeuser", "password": "$6$sR1OEFM1KVuMeBUt$NhanSmm91.BspCYlMtrjYhc71FElgaCP7uSUAwhtQVFGcYa7.8VPMmRce77yS8FLy6XSYBtcCeZCJhnLOicc/.", "last_changed": null, "minimum": 0, "maximum": 99999, "warn": 7, "inactive": null, "expire": null}, {"username": "dockerroot", "password": "!!", "last_changed": 18123, "minimum": null, "maximum": null, "warn": null, "inactive": null, "expire": null}]
|
||||
21
tests/fixtures/centos-7.7/shadow.out
vendored
Normal file
21
tests/fixtures/centos-7.7/shadow.out
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
root:$6$27lBiByDWdiM7lvJ$ulWkJyfKNbqDnrIKPLhUCGanKcS5TdY3ZasKMR/v2dl0mHn0s28LcxTXMqqOV0d6tww0U4gmgYZezgAf/F8Pz.::0:99999:7:::
|
||||
bin:*:17834:0:99999:7:::
|
||||
daemon:*:17834:0:99999:7:::
|
||||
adm:*:17834:0:99999:7:::
|
||||
lp:*:17834:0:99999:7:::
|
||||
sync:*:17834:0:99999:7:::
|
||||
shutdown:*:17834:0:99999:7:::
|
||||
halt:*:17834:0:99999:7:::
|
||||
mail:*:17834:0:99999:7:::
|
||||
operator:*:17834:0:99999:7:::
|
||||
games:*:17834:0:99999:7:::
|
||||
ftp:*:17834:0:99999:7:::
|
||||
nobody:*:17834:0:99999:7:::
|
||||
systemd-network:!!:18123::::::
|
||||
dbus:!!:18123::::::
|
||||
polkitd:!!:18123::::::
|
||||
sshd:!!:18123::::::
|
||||
postfix:!!:18123::::::
|
||||
chrony:!!:18123::::::
|
||||
joeuser:$6$sR1OEFM1KVuMeBUt$NhanSmm91.BspCYlMtrjYhc71FElgaCP7uSUAwhtQVFGcYa7.8VPMmRce77yS8FLy6XSYBtcCeZCJhnLOicc/.::0:99999:7:::
|
||||
dockerroot:!!:18123::::::
|
||||
1
tests/fixtures/centos-7.7/who-a.json
vendored
Normal file
1
tests/fixtures/centos-7.7/who-a.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"event": "reboot", "time": "2020-02-29 12:13"}, {"event": "login", "tty": "tty1", "time": "2020-02-29 12:13", "pid": 841, "comment": "id=tty1"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "ttyS0", "time": "2020-02-29 12:14", "idle": ".", "pid": 840}, {"event": "run-level 3", "time": "2020-02-29 12:13"}, {"user": "kbrazil", "writeable_tty": "+", "tty": "pts/0", "time": "2020-02-29 18:43", "idle": "00:11", "pid": 3709, "from": "192.168.71.1"}, {"tty": "pts/1", "time": "2020-02-29 18:28", "pid": 3381, "comment": "id=ts/1 term=0 exit=0"}]
|
||||
6
tests/fixtures/centos-7.7/who-a.out
vendored
Normal file
6
tests/fixtures/centos-7.7/who-a.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
system boot 2020-02-29 12:13
|
||||
LOGIN tty1 2020-02-29 12:13 841 id=tty1
|
||||
kbrazil + ttyS0 2020-02-29 12:14 . 840
|
||||
run-level 3 2020-02-29 12:13
|
||||
kbrazil + pts/0 2020-02-29 18:43 00:11 3709 (192.168.71.1)
|
||||
pts/1 2020-02-29 18:28 3381 id=ts/1 term=0 exit=0
|
||||
1
tests/fixtures/centos-7.7/who.json
vendored
Normal file
1
tests/fixtures/centos-7.7/who.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"user": "kbrazil", "tty": "ttyS0", "time": "2020-02-29 12:14"}, {"user": "kbrazil", "tty": "pts/0", "time": "2020-02-29 18:43", "from": "192.168.71.1"}]
|
||||
2
tests/fixtures/centos-7.7/who.out
vendored
Normal file
2
tests/fixtures/centos-7.7/who.out
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
kbrazil ttyS0 2020-02-29 12:14
|
||||
kbrazil pts/0 2020-02-29 18:43 (192.168.71.1)
|
||||
33
tests/fixtures/create_fixtures.sh
vendored
33
tests/fixtures/create_fixtures.sh
vendored
@@ -35,6 +35,26 @@ jobs > jobs.out
|
||||
ls / > ls.out
|
||||
ls -al / > ls-al.out
|
||||
ls -alh / > ls-alh.out
|
||||
|
||||
ls -R /usr > ls-R.out
|
||||
ls -alR /usr > ls-alR.out
|
||||
ls /usr/* > ls-glob.out
|
||||
|
||||
cd /tmp/lstest
|
||||
touch 'a regular filename'
|
||||
touch $'\nthis file starts with one newline'
|
||||
touch $'\n\n\n\nthis file starts with four newlines'
|
||||
touch $'this file has\na newline inside'
|
||||
touch $'this file has\n\n\n\nfour contiguous newlines inside'
|
||||
touch $'this file\nhas\nsix\n\nnewlines\n\nwithin'
|
||||
touch $'\n\nthis file has\na combination\n\n\nof everything\n\n\n\n'
|
||||
cd /tmp
|
||||
ls -R > ~/utils/ls-R-newlines.out
|
||||
ls -lR > ~/utils/ls-lR-newlines.out
|
||||
cd lstest
|
||||
ls > ~/utils/ls-newlines.out
|
||||
ls -l > ~/utils/ls-l-newlines.out
|
||||
|
||||
lsblk > lsblk.out
|
||||
lsblk -o +KNAME,FSTYPE,LABEL,UUID,PARTLABEL,PARTUUID,RA,MODEL,SERIAL,STATE,OWNER,GROUP,MODE,ALIGNMENT,MIN-IO,OPT-IO,PHY-SEC,LOG-SEC,ROTA,SCHED,RQ-SIZE,DISC-ALN,DISC-GRAN,DISC-MAX,DISC-ZERO,WSAME,WWN,RAND,PKNAME,HCTL,TRAN,REV,VENDOR > lsblk-allcols.out
|
||||
lsmod > lsmod.out
|
||||
@@ -68,3 +88,16 @@ systemctl -a list-jobs > systemctl-jobs.out
|
||||
du /usr > du.out
|
||||
pip3 list > pip-list.out
|
||||
pip3 show wheel pip jc > pip-show.out
|
||||
|
||||
blkid > blkid.out
|
||||
blkid /dev/sda2 > blkid-sda2.out
|
||||
sudo blkid -ip /dev/sda2 /dev/sda1 > blkid-ip-multi.out
|
||||
sudo blkid -o udev -ip /dev/sr0 > blkid-ip-udev.out
|
||||
sudo blkid -o udev -ip /dev/sda2 /dev/sda1 > blkid-ip-udev-multi.out
|
||||
|
||||
last > last.out
|
||||
last -w | cat > last-w.out
|
||||
sudo lastb > lastb.out
|
||||
|
||||
cat /etc/group > group.out
|
||||
sudo cat /etc/gshadow > gshadow.out
|
||||
|
||||
20
tests/fixtures/generic/csv-biostats.csv
vendored
Normal file
20
tests/fixtures/generic/csv-biostats.csv
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"Name", "Sex", "Age", "Height (in)", "Weight (lbs)"
|
||||
"Alex", "M", 41, 74, 170
|
||||
"Bert", "M", 42, 68, 166
|
||||
"Carl", "M", 32, 70, 155
|
||||
"Dave", "M", 39, 72, 167
|
||||
"Elly", "F", 30, 66, 124
|
||||
"Fran", "F", 33, 66, 115
|
||||
"Gwen", "F", 26, 64, 121
|
||||
"Hank", "M", 30, 71, 158
|
||||
"Ivan", "M", 53, 72, 175
|
||||
"Jake", "M", 32, 69, 143
|
||||
"Kate", "F", 47, 69, 139
|
||||
"Luke", "M", 34, 72, 163
|
||||
"Myra", "F", 23, 62, 98
|
||||
"Neil", "M", 36, 75, 160
|
||||
"Omar", "M", 38, 70, 145
|
||||
"Page", "F", 31, 67, 135
|
||||
"Quin", "M", 29, 71, 176
|
||||
"Ruth", "F", 28, 65, 131
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user