问题
I am trying to automate a VI edit for a command similar to crontab editing via Shell script but not working for me so far.
Here is the final json with admin as true:
'{"name":"SQLSRVR","admin":"true","json_class":"Chef::ApiClient","chef_type":"client"}'
As you can see the EDITOR environment variable has to be set or passed as command line option -e
[root@vrhost user]# knife client edit SQLSRVR
ERROR: RuntimeError: Please set EDITOR environment variable
[root@vrhost user]# knife client edit
USAGE: knife client edit CLIENT (options)
-s, --server-url URL Chef Server URL
-k, --key KEY API Client Key
--[no-]color Use colored output, defaults to enabled
-c, --config CONFIG The configuration file to use
--defaults Accept default values for all questions
-d, --disable-editing Do not open EDITOR, just accept the data as is
-e, --editor EDITOR Set the editor to use for interactive commands
-E, --environment ENVIRONMENT Set the Chef environment
-F, --format FORMAT Which format to use for output
-u, --user USER API Client Username
--print-after Show the data after a destructive operation
-V, --verbose More verbose output. Use twice for max verbosity
-v, --version Show chef version
-y, --yes Say yes to all prompts for confirmation
-h, --help Show this message
FATAL: You must specify a client name
The below command opens a vim editor for editing to make the change from ["admin": "false"] to ["admin": "true"]:
[root@vrhost user]# knife client edit SQLSRVR -e vim
{
"name": "SQLSRVR",
"admin": false,
"json_class": "Chef::ApiClient",
"chef_type": "client",
}
I am trying to do this through a shell script and would like to automate it and tried many options but had no luck so far.
[root@vrhost ~]# (echo ^[:g/false/s/false/true/^[:wq!^M) | knife client edit SQLSRVR -e vim
Vim: Warning: Input is not from a terminal
Object unchanged, not saving
or
[root@vrhost user]# echo (^[echo '{"name":"SQLSRVR","admin":"true","json_class":"Chef::ApiClient","chef_type":"client"}'^[:w q!^M) | knife client edit SQLSRVR -e
[root@vrhost ~]# knife client show SQLSRVR
admin: false
chef_type: client
json_class: Chef::ApiClient
name: SQLSRVR
this is very similar to automating crontab editing via shell script but this has not been working for me.
回答1:
Unless you really need special Vim capabilities, you're probably better off using non-interactive tools like sed
, awk
, or Perl / Python / Ruby / your favorite scripting language here.
That said, you can use Vim non-interactively, using silent batch mode.
vim -T dumb --noplugin -n -es -S "commands.ex" "filespec"
Instead of the external script to read the commands from via -S "commands.ex"
, you can also give a few commands directly via -c cmd1 -c cmd2
. See :help -s-ex
for more information.
回答2:
Check out
$ knife client edit --help
[...]
-d, --disable-editing Do not open EDITOR, just accept the data as is
So I guess you can change the values without editing in vim. Just:
- get the client data in json format.
- replace needed values with sed.
- upload the data from file.
Code:
$ knife client show -Fj SQLSRVR > SQLSRVR.json
$ sed -i.old "s/\"admin\": true,/\"admin\": false,/" SQLSRVR.json
$ knife client edit -d SQLSRVR < SQLSRVR.json
Something like that.
回答3:
Here are some links to references:
i) http://mirror.hep.wisc.edu/stable/chef/chef-server-webui/app/controllers/clients_controller.rb
ii) http://www.rubydoc.info/github/opscode/chef/master/Shell/Extensions - tried but unable to get it to work
Finally did the following (it does give 409 the 2nd time on call and I did not need to do it a 2nd time):
# call to below rb, CLIENTNAME is the name of the client and STATE is true/false
$ knife exec clienttransform.rb CLIENTNAME STATE
$ cat clienttransform.rb
Chef::Config[:solo] = false
class Company
class TransformClient
attr_accessor :clientname
attr_accessor :isclientadmin
def initialize(client_name, is_client_admin)
@clientname = client_name
@isclientadmin = is_client_admin
end
def transform
client=Chef::ApiClient.load(@clientname)
# puts "client.name : " + client.name
# puts "client.admin : " + client.admin.to_s
# puts "XX - clientname : " + @clientname
# puts "XX - isclientadmin : " + @isclientadmin.to_s
boolisclientadmin = !!@isclientadmin
client.admin(boolisclientadmin)
client.save()
end
end
end
client_name = ARGV[2].to_s()
is_client_admin = ARGV[3].to_s()
# puts "YY - client_name : " + client_name
# puts "YY - is_client_admin : " + is_client_admin
trc = Company::TransformClient.new(client_name, is_client_admin)
trc.transform
exit 0
回答4:
Just set your editor and it will work. In my case I use vim editor that's why my command was as follows:
export EDITOR=vim
来源:https://stackoverflow.com/questions/14941296/automate-vim-editor-and-update-values-using-shell-script-similar-to-editing-cro