cs-sh 20260912.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cs_sh-20260912.1/PKG-INFO +105 -0
- cs_sh-20260912.1/pyproject.toml +132 -0
- cs_sh-20260912.1/src/cs/sh.py +135 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cs-sh
|
|
3
|
+
Version: 20260912.1
|
|
4
|
+
Summary: Convenience functions for constructing shell commands.
|
|
5
|
+
Keywords: python2,python3
|
|
6
|
+
Author-email: Cameron Simpson <cs@cskk.id.au>
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: Programming Language :: Python
|
|
9
|
+
Classifier: Programming Language :: Python :: 2
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
16
|
+
Project-URL: MonoRepo Commits, https://bitbucket.org/cameron_simpson/css/commits/branch/main
|
|
17
|
+
Project-URL: Monorepo Git Mirror, https://github.com/cameron-simpson/css
|
|
18
|
+
Project-URL: Monorepo Hg/Mercurial Mirror, https://hg.sr.ht/~cameron-simpson/css
|
|
19
|
+
Project-URL: Source, https://github.com/cameron-simpson/css/blob/main/lib/python/cs/sh.py
|
|
20
|
+
|
|
21
|
+
Convenience functions for constructing shell commands.
|
|
22
|
+
|
|
23
|
+
*Latest release 20260912.1*:
|
|
24
|
+
Fix project specification.
|
|
25
|
+
|
|
26
|
+
Functions for safely constructing shell command lines from bare strings.
|
|
27
|
+
Somewhat like the inverse of the shlex stdlib module.
|
|
28
|
+
|
|
29
|
+
As of Python 3.3 the function `shlex.quote()` does what `quotestr()` does.
|
|
30
|
+
|
|
31
|
+
As of Python 3.8 the function `shlex.join()` does what `quoteargv()` does.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
Short summary:
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
* `main_shqstr`: shqstr: emit shell-quoted form of the command line arguments.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
* `quote`: Quote the supplied strings, return a list of the quoted strings.
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
* `quoteargv`: Quote strings, assemble into command string.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
* `quotestr`: Quote a string for use on a shell command line.
|
|
48
|
+
|
|
49
|
+
# Functions
|
|
50
|
+
|
|
51
|
+
## main_shqstr(argv=None)
|
|
52
|
+
|
|
53
|
+
shqstr: emit shell-quoted form of the command line arguments.
|
|
54
|
+
|
|
55
|
+
## quote(args)
|
|
56
|
+
|
|
57
|
+
Quote the supplied strings, return a list of the quoted strings.
|
|
58
|
+
|
|
59
|
+
As of Python 3.8 the function `shlex.join()` probably does
|
|
60
|
+
what you would have done with the result of this function
|
|
61
|
+
i.e. join the resulting strings together.
|
|
62
|
+
|
|
63
|
+
## quoteargv(argv)
|
|
64
|
+
|
|
65
|
+
Quote strings, assemble into command string.
|
|
66
|
+
|
|
67
|
+
## quotestr(s)
|
|
68
|
+
|
|
69
|
+
Quote a string for use on a shell command line.
|
|
70
|
+
|
|
71
|
+
As of Python 3.3 the function `shlex.quote()` is available for this.
|
|
72
|
+
|
|
73
|
+
# Release Log
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
*Release 20260912.1*:
|
|
78
|
+
Fix project specification.
|
|
79
|
+
|
|
80
|
+
*Release 20260912*:
|
|
81
|
+
Rename quotecmd to quoteargv.
|
|
82
|
+
|
|
83
|
+
*Release 20210316*:
|
|
84
|
+
Minor doc update.
|
|
85
|
+
|
|
86
|
+
*Release 20180613*:
|
|
87
|
+
Rework quotestr significantly to provide somewhat friendlier quoting, include "," in the SAFECHARS.
|
|
88
|
+
|
|
89
|
+
*Release 20170903.2*:
|
|
90
|
+
bugfix __main__ boilerplate after setuptools workaround
|
|
91
|
+
|
|
92
|
+
*Release 20170903.1*:
|
|
93
|
+
workaround setuptool's slightly dumb console_scripts call of a "main" function
|
|
94
|
+
|
|
95
|
+
*Release 20170903*:
|
|
96
|
+
shqstr command; new quotecmd(argv) function
|
|
97
|
+
|
|
98
|
+
*Release 20150118*:
|
|
99
|
+
Extend SAFECHARS to include colon.
|
|
100
|
+
|
|
101
|
+
*Release 20150111*:
|
|
102
|
+
minor cleanup
|
|
103
|
+
|
|
104
|
+
*Release 20150107*:
|
|
105
|
+
initial standalone public release
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "cs-sh"
|
|
3
|
+
description = "Convenience functions for constructing shell commands."
|
|
4
|
+
authors = [
|
|
5
|
+
{ name = "Cameron Simpson", email = "cs@cskk.id.au" },
|
|
6
|
+
]
|
|
7
|
+
keywords = [
|
|
8
|
+
"python2",
|
|
9
|
+
"python3",
|
|
10
|
+
]
|
|
11
|
+
dependencies = []
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python",
|
|
14
|
+
"Programming Language :: Python :: 2",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
20
|
+
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
|
|
21
|
+
]
|
|
22
|
+
version = "20260912.1"
|
|
23
|
+
|
|
24
|
+
[project.license]
|
|
25
|
+
text = "GNU General Public License v3 or later (GPLv3+)"
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
"Monorepo Hg/Mercurial Mirror" = "https://hg.sr.ht/~cameron-simpson/css"
|
|
29
|
+
"Monorepo Git Mirror" = "https://github.com/cameron-simpson/css"
|
|
30
|
+
"MonoRepo Commits" = "https://bitbucket.org/cameron_simpson/css/commits/branch/main"
|
|
31
|
+
Source = "https://github.com/cameron-simpson/css/blob/main/lib/python/cs/sh.py"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
shqstr = "cs.sh:main_shqstr"
|
|
35
|
+
|
|
36
|
+
[project.readme]
|
|
37
|
+
text = """
|
|
38
|
+
Convenience functions for constructing shell commands.
|
|
39
|
+
|
|
40
|
+
*Latest release 20260912.1*:
|
|
41
|
+
Fix project specification.
|
|
42
|
+
|
|
43
|
+
Functions for safely constructing shell command lines from bare strings.
|
|
44
|
+
Somewhat like the inverse of the shlex stdlib module.
|
|
45
|
+
|
|
46
|
+
As of Python 3.3 the function `shlex.quote()` does what `quotestr()` does.
|
|
47
|
+
|
|
48
|
+
As of Python 3.8 the function `shlex.join()` does what `quoteargv()` does.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
Short summary:
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
* `main_shqstr`: shqstr: emit shell-quoted form of the command line arguments.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
* `quote`: Quote the supplied strings, return a list of the quoted strings.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
* `quoteargv`: Quote strings, assemble into command string.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
* `quotestr`: Quote a string for use on a shell command line.
|
|
65
|
+
|
|
66
|
+
# Functions
|
|
67
|
+
|
|
68
|
+
## main_shqstr(argv=None)
|
|
69
|
+
|
|
70
|
+
shqstr: emit shell-quoted form of the command line arguments.
|
|
71
|
+
|
|
72
|
+
## quote(args)
|
|
73
|
+
|
|
74
|
+
Quote the supplied strings, return a list of the quoted strings.
|
|
75
|
+
|
|
76
|
+
As of Python 3.8 the function `shlex.join()` probably does
|
|
77
|
+
what you would have done with the result of this function
|
|
78
|
+
i.e. join the resulting strings together.
|
|
79
|
+
|
|
80
|
+
## quoteargv(argv)
|
|
81
|
+
|
|
82
|
+
Quote strings, assemble into command string.
|
|
83
|
+
|
|
84
|
+
## quotestr(s)
|
|
85
|
+
|
|
86
|
+
Quote a string for use on a shell command line.
|
|
87
|
+
|
|
88
|
+
As of Python 3.3 the function `shlex.quote()` is available for this.
|
|
89
|
+
|
|
90
|
+
# Release Log
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
*Release 20260912.1*:
|
|
95
|
+
Fix project specification.
|
|
96
|
+
|
|
97
|
+
*Release 20260912*:
|
|
98
|
+
Rename quotecmd to quoteargv.
|
|
99
|
+
|
|
100
|
+
*Release 20210316*:
|
|
101
|
+
Minor doc update.
|
|
102
|
+
|
|
103
|
+
*Release 20180613*:
|
|
104
|
+
Rework quotestr significantly to provide somewhat friendlier quoting, include \",\" in the SAFECHARS.
|
|
105
|
+
|
|
106
|
+
*Release 20170903.2*:
|
|
107
|
+
bugfix __main__ boilerplate after setuptools workaround
|
|
108
|
+
|
|
109
|
+
*Release 20170903.1*:
|
|
110
|
+
workaround setuptool's slightly dumb console_scripts call of a \"main\" function
|
|
111
|
+
|
|
112
|
+
*Release 20170903*:
|
|
113
|
+
shqstr command; new quotecmd(argv) function
|
|
114
|
+
|
|
115
|
+
*Release 20150118*:
|
|
116
|
+
Extend SAFECHARS to include colon.
|
|
117
|
+
|
|
118
|
+
*Release 20150111*:
|
|
119
|
+
minor cleanup
|
|
120
|
+
|
|
121
|
+
*Release 20150107*:
|
|
122
|
+
initial standalone public release"""
|
|
123
|
+
content-type = "text/markdown"
|
|
124
|
+
|
|
125
|
+
[build-system]
|
|
126
|
+
build-backend = "flit_core.buildapi"
|
|
127
|
+
requires = [
|
|
128
|
+
"flit_core >=3.2,<4",
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
[tool.flit.module]
|
|
132
|
+
name = "cs.sh"
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/usr/bin/python
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
r'''
|
|
5
|
+
Convenience functions for constructing shell commands.
|
|
6
|
+
|
|
7
|
+
Functions for safely constructing shell command lines from bare strings.
|
|
8
|
+
Somewhat like the inverse of the shlex stdlib module.
|
|
9
|
+
|
|
10
|
+
As of Python 3.3 the function `shlex.quote()` does what `quotestr()` does.
|
|
11
|
+
|
|
12
|
+
As of Python 3.8 the function `shlex.join()` does what `quoteargv()` does.
|
|
13
|
+
'''
|
|
14
|
+
|
|
15
|
+
import string
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
__version__ = '20260912.1'
|
|
19
|
+
|
|
20
|
+
DISTINFO = {
|
|
21
|
+
'description':
|
|
22
|
+
"Convenience functions for constructing shell commands.",
|
|
23
|
+
'keywords': ["python2", "python3"],
|
|
24
|
+
'classifiers': [
|
|
25
|
+
"Programming Language :: Python",
|
|
26
|
+
"Programming Language :: Python :: 2",
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
],
|
|
29
|
+
'install_requires': [],
|
|
30
|
+
'entry_points': {
|
|
31
|
+
'console_scripts': {
|
|
32
|
+
'shqstr': 'cs.sh:main_shqstr'
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# characters than do not need to be quoted
|
|
38
|
+
SAFECHARS = string.digits + string.ascii_letters + '-+_.,/:'
|
|
39
|
+
|
|
40
|
+
def quote(args):
|
|
41
|
+
''' Quote the supplied strings, return a list of the quoted strings.
|
|
42
|
+
|
|
43
|
+
As of Python 3.8 the function `shlex.join()` probably does
|
|
44
|
+
what you would have done with the result of this function
|
|
45
|
+
i.e. join the resulting strings together.
|
|
46
|
+
'''
|
|
47
|
+
return [quotestr(s) for s in args]
|
|
48
|
+
|
|
49
|
+
def quotestr(s):
|
|
50
|
+
''' Quote a string for use on a shell command line.
|
|
51
|
+
|
|
52
|
+
As of Python 3.3 the function `shlex.quote()` is available for this.
|
|
53
|
+
'''
|
|
54
|
+
# decide how to quote the string:
|
|
55
|
+
# - empty string: return ''
|
|
56
|
+
# - all safe: do not quote
|
|
57
|
+
# - no single quotes: just single quote the string
|
|
58
|
+
# - funky quoting
|
|
59
|
+
if not s:
|
|
60
|
+
return "''"
|
|
61
|
+
q_count = 0
|
|
62
|
+
unsafe_count = 0
|
|
63
|
+
switch_count = 0
|
|
64
|
+
safe = True
|
|
65
|
+
for c in s:
|
|
66
|
+
if c == "'":
|
|
67
|
+
q_count += 1
|
|
68
|
+
new_safe = False
|
|
69
|
+
elif c not in SAFECHARS:
|
|
70
|
+
unsafe_count += 1
|
|
71
|
+
new_safe = False
|
|
72
|
+
else:
|
|
73
|
+
new_safe = True
|
|
74
|
+
if safe ^ new_safe:
|
|
75
|
+
switch_count += 1
|
|
76
|
+
safe = new_safe
|
|
77
|
+
if q_count == 0 and unsafe_count == 0:
|
|
78
|
+
# all safe
|
|
79
|
+
return s
|
|
80
|
+
if q_count == 0:
|
|
81
|
+
# unsafe but no single quotes
|
|
82
|
+
return "'" + s + "'"
|
|
83
|
+
|
|
84
|
+
def flush():
|
|
85
|
+
''' Output the pending characters, which are either all safe or all unsafe.
|
|
86
|
+
'''
|
|
87
|
+
if offset > start:
|
|
88
|
+
part = s[start:offset]
|
|
89
|
+
if not safe:
|
|
90
|
+
if len(part) == 1:
|
|
91
|
+
qparts.append("\\")
|
|
92
|
+
else:
|
|
93
|
+
qparts.append("'")
|
|
94
|
+
qparts.append(part)
|
|
95
|
+
if not safe:
|
|
96
|
+
if len(part) > 1:
|
|
97
|
+
qparts.append("'")
|
|
98
|
+
|
|
99
|
+
qparts = []
|
|
100
|
+
start = 0
|
|
101
|
+
safe = True # not in quotes
|
|
102
|
+
for offset, c in enumerate(s):
|
|
103
|
+
if c == "'" or (safe and c == '\\'):
|
|
104
|
+
flush()
|
|
105
|
+
qparts.append('\\')
|
|
106
|
+
qparts.append(c)
|
|
107
|
+
start = offset + 1 # do not include this character in the flushable set
|
|
108
|
+
new_safe = False
|
|
109
|
+
else:
|
|
110
|
+
new_safe = c in SAFECHARS
|
|
111
|
+
if safe ^ new_safe:
|
|
112
|
+
# mode change
|
|
113
|
+
flush()
|
|
114
|
+
start = offset
|
|
115
|
+
safe = new_safe
|
|
116
|
+
# advance past final position
|
|
117
|
+
offset += 1
|
|
118
|
+
flush()
|
|
119
|
+
return ''.join(qparts)
|
|
120
|
+
|
|
121
|
+
def quoteargv(argv):
|
|
122
|
+
''' Quote strings, assemble into command string.
|
|
123
|
+
'''
|
|
124
|
+
return ' '.join(quote(argv))
|
|
125
|
+
|
|
126
|
+
def main_shqstr(argv=None):
|
|
127
|
+
''' shqstr: emit shell-quoted form of the command line arguments.
|
|
128
|
+
'''
|
|
129
|
+
if argv is None:
|
|
130
|
+
argv = sys.argv
|
|
131
|
+
argv.pop(0)
|
|
132
|
+
print(quoteargv(argv))
|
|
133
|
+
|
|
134
|
+
if __name__ == '__main__':
|
|
135
|
+
sys.exit(main_shqstr())
|