3

I need to replace a single character in a/etc/request-key.conf

The file format is;

###############################################################################
#
# Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version
# 2 of the License, or (at your option) any later version.
#
###############################################################################


###############################################################################
#
# We can run programs or scripts
# - Macro substitutions in arguments:
#   %%...   %...
#   %o  operation name
#   %k  ID of key being operated upon
#   %t  type of key being operated upon
#   %d  description of key being operated upon
#   %c  callout info
#   %u  UID of requestor
#   %g  GID of requestor
#   %T  thread keyring of requestor (may be 0)
#   %P  process keyring of requestor (may be 0)
#   %S  session keyring of requestor (may be the user's default session)
#
################################################################################

#OP TYPE    DESCRIPTION CALLOUT INFO    PROGRAM ARG1 ARG2 ARG3 ...
#====== ======= =============== =============== ===============================
create  dns_resolver *      *               /sbin/key.dns_resolver %k
create  user    debug:*     negate      /bin/keyctl negate %k 30 %S
create  user    debug:*         rejected        /bin/keyctl reject %k 30 %c %S
create  user    debug:*         expired         /bin/keyctl reject %k 30 %c %S
create  user    debug:*         revoked         /bin/keyctl reject %k 30 %c %S
create  user    debug:loop:*    *       |/bin/cat
create  user    debug:*     *       /usr/share/keyutils/request-key-debug.sh %k %d %c %S
create  cifs.spnego *   *       /usr/sbin/cifs.upcall -c %k
create  dns_resolver    *   *       /usr/sbin/cifs.upcall %k
negate  *   *       *       /bin/keyctl negate %k 30 %S

So I need the 3rd last line to go from;

create cifs.spnego * * /usr/sbin/cifs.upcall -c %k

to;

create cifs.spnego * * /usr/sbin/cifs.upcall -t %k

I have tried;

sed -i 's/^\(create cifs.spnego *cifs.upcall\) \(%k\)/\1 -t \2/' /etc/request-key.conf

Bu treally I just need to replace the -c with a -t

8

The golden rule in regular expressions is: less is more. Always try and find the simplest expression that is sufficient to target your search string. So instead of trying to match the entire line, look for a small, but unique, string:

$ grep -- -c file
create  cifs.spnego *   *       /usr/sbin/cifs.upcall -c %k

I saved your file as file and, as you can see, there is only one case of -c in the file. So all you need is (note the -i.bak, that will create a backup file):

sed -i.bak 's/-c/-t/' /etc/request-key.conf

If you want to be more prudent and make sure you match only your target line without searching first, just change the -c on any lines starting with create cifs.spnego. Note the use of -E for extended regular expressions and using \s+ (1 or more whitespace) instead of trying to write multiple spaces:

sed -Ei.bak 's/^(create\s+cifs\.spnego.*cifs.upcall\s+)-c/\1 -t/' /etc/request-key.conf

Since you don't need to make any changes after the -c, there is no reason to try and match it: less is more.


The reason your attempt failed is because * is a multiplier in regular expressions, it means "0 or more". So when you have cifs.spnego *cifs.upcall, that looks for cifs.spnego, then 0 or more spaces, followed by cifs.upcall. Your line, however, was:

create  cifs.spnego *   *       /usr/sbin/cifs.upcall  -t %k

To match that, you need to match cifs.spnego, then a space, then a *, then more spaces, and another *, then /usr/sbin/ and only then do you have cifs.upcall. To match all of those, you would need (you need \* to match the character *):

/^create  cifs.spnego \*   \*       cifs.upcall/

Or, since less is more, simply:

/^create  cifs.spnego .*cifs.upcall/

The .* means "anything".

| improve this answer | |
  • I think you want s/-c/-t not s/-c/-k/ if I read the project scope correctly. Still +1 for "less is more". – WinEunuuchs2Unix Sep 13 '19 at 15:09
  • 1
    I often favor separating the context pattern from the replacement pattern in situations like this - for example sed '/cifs.spnego/ s/-c/-t/' – steeldriver Sep 13 '19 at 15:12
  • @WinEunuuchs2Unix D'oh! Indeed I do, thanks! – terdon Sep 13 '19 at 15:20
  • @steeldriver yes, that makes a lot of sense. – terdon Sep 13 '19 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.