Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit13d23b4

Browse files
committed
chown: Add chown.py
1 parent6383f56 commit13d23b4

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed

‎userland/utilities/chown.py‎

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
importre
2+
3+
importshutil
4+
importsys
5+
frompathlibimportPath
6+
7+
fromtqdmimporttqdm
8+
9+
from ..importcore
10+
11+
12+
CHOWN_PATTERN=re.compile("^([^:]+)?(:([^:]+))?$")
13+
14+
parser=core.create_parser(
15+
usage=(
16+
"%prog [OPTION]... [USER][:[GROUP]] FILE...",
17+
"%prog [OPTION]... --reference=RFILE FILE...",
18+
),
19+
description="Change the user and/or group ownership of each FILE.",
20+
)
21+
22+
parser.add_option(
23+
"-f",
24+
"--silent",
25+
"--quiet",
26+
dest="verbosity",
27+
action="store_const",
28+
const=0,
29+
default=1,
30+
help="suppress most error messages",
31+
)
32+
parser.add_option(
33+
"-c",
34+
"--changes",
35+
dest="verbosity",
36+
action="store_const",
37+
const=2,
38+
help="report only when changes are made",
39+
)
40+
parser.add_option(
41+
"-v",
42+
"--verbose",
43+
dest="verbosity",
44+
action="store_const",
45+
const=3,
46+
help="print a diagnostic for each file",
47+
)
48+
49+
parser.add_option(
50+
"--progress",
51+
dest="progress",
52+
action="store_true",
53+
help="show a progress bar when changing groups",
54+
)
55+
parser.add_option(
56+
"--no-progress",
57+
dest="progress",
58+
action="store_false",
59+
default=False,
60+
help="do not show a progress bar (default)",
61+
)
62+
63+
parser.add_option(
64+
"--dereference",
65+
action="store_true",
66+
default=True,
67+
help="affect symlink referents instead of the symlinks themselves (default)",
68+
)
69+
parser.add_option(
70+
"-h",
71+
"--no-dereference",
72+
dest="dereference",
73+
action="store_false",
74+
help="opposite of --dereference",
75+
)
76+
77+
parser.add_option(
78+
"--no-preserve-root",
79+
dest="preserve_root",
80+
action="store_false",
81+
default=False,
82+
help="do not treat '/' specially (default)",
83+
)
84+
parser.add_option(
85+
"--preserve-root",
86+
dest="preserve_root",
87+
action="store_true",
88+
help="fail to operate recursively on '/'",
89+
)
90+
91+
parser.add_option(
92+
"--from",
93+
dest="from_spec",# prevent name collision with the `from` keyword
94+
metavar="[CURRENT_OWNER][:[CURRENT_GROUP]]",
95+
help="only affect files with CURRENT_OWNER and CURRENT_GROUP"
96+
" (either is optional and only checked if given)",
97+
)
98+
99+
parser.add_option("--reference",metavar="RFILE")
100+
101+
parser.add_option(
102+
"-R","--recursive",action="store_true",help="operate on directories recursively"
103+
)
104+
parser.add_option(
105+
"-H",
106+
dest="recurse_mode",
107+
action="store_const",
108+
const="H",
109+
help="traverse directory symlinks only if they were given as command line arguments",
110+
)
111+
parser.add_option(
112+
"-L",
113+
dest="recurse_mode",
114+
action="store_const",
115+
const="L",
116+
help="traverse all directory symlinks encountered",
117+
)
118+
parser.add_option(
119+
"-P",
120+
dest="recurse_mode",
121+
action="store_const",
122+
const="P",
123+
default="P",
124+
help="do not traverse any symlinks (default)",
125+
)
126+
127+
128+
@core.command(parser)
129+
defpython_userland_chown(opts,args):
130+
ifnotargs:
131+
parser.error("missing operand")
132+
133+
from_uid:int|None=None
134+
from_gid:int|None=None
135+
136+
ifopts.from_spec:
137+
from_uid,from_gid=core.parse_onwer_spec(parser,opts.from_spec)
138+
139+
chown_args= {"follow_symlinks":opts.dereference}
140+
141+
ifopts.reference:
142+
try:
143+
ref_stat=Path(opts.reference).stat(follow_symlinks=True)
144+
exceptOSErrorase:
145+
print(e,file=sys.stderr)
146+
return1
147+
148+
chown_args["user"]=ref_stat.st_uid
149+
chown_args["group"]=ref_stat.st_gid
150+
else:
151+
owner_spec=args.pop(0)
152+
153+
ifnotargs:
154+
parser.error(f"missing operand after '{owner_spec}'")
155+
156+
ifnot (owner_match:=CHOWN_PATTERN.match(owner_spec)):
157+
parser.error(f"invalid owner spec:{owner_spec}")
158+
159+
chown_args["user"]= (
160+
core.parse_user(parser,owner_match.group(1))
161+
ifowner_match.group(1)
162+
elseNone
163+
)
164+
chown_args["group"]= (
165+
core.parse_group(parser,owner_match.group(3))
166+
ifowner_match.group(3)
167+
elseNone
168+
)
169+
170+
failed=False
171+
172+
forfileincore.traverse_files(
173+
(tqdm(args,ascii=True,desc="Changing ownership")ifopts.progresselseargs),
174+
recurse_mode=opts.recurse_modeifopts.recursiveelseNone,
175+
preserve_root=opts.preserve_root,
176+
):
177+
ifnotfile:
178+
failed=True
179+
continue
180+
181+
try:
182+
stat=file.stat(follow_symlinks=opts.dereference)
183+
prev_uid=stat.st_uid
184+
prev_gid=stat.st_gid
185+
exceptOSErrorase:
186+
failed=True
187+
print(e,file=sys.stderr)
188+
print(
189+
f"failed to change ownership of '{file}' to{owner_spec}",
190+
file=sys.stderr,
191+
)
192+
continue
193+
194+
prev_uname=core.user_display_name_from_id(prev_uid)
195+
prev_gname=core.group_display_name_from_id(prev_gid)
196+
197+
if (from_uidisnotNoneandprev_uid!=from_uid)or (
198+
from_gidisnotNoneandprev_gid!=from_gid
199+
):
200+
ifopts.verbosity>2:
201+
print(f"ownership of '{file}' retained as{prev_uname}:{prev_gname}")
202+
continue
203+
204+
try:
205+
shutil.chown(file,**chown_args)
206+
exceptOSErrorase:
207+
failed=True
208+
ifopts.verbosity:
209+
print(e,file=sys.stderr)
210+
print(
211+
f"failed to change ownership of '{file}' to{owner_spec}",
212+
file=sys.stderr,
213+
)
214+
continue
215+
216+
ifprev_uid==chown_args["user"]orprev_gid==chown_args["group"]:
217+
ifopts.verbosity>2:
218+
print(f"ownership of '{file}' retained as{prev_uname}:{prev_gname}")
219+
elifopts.verbosity>1:
220+
print(
221+
f"changed ownership of '{file}' from"
222+
f"{prev_uname}:{prev_gname} to{owner_spec}"
223+
)
224+
225+
returnint(failed)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp