Example #1
0
def _rosparam_cmd_get_dump(cmd, argv):
    """
    Process command line for rosparam get/dump, e.g.::
      rosparam get param
      rosparam dump file.yaml [namespace]
    @param cmd: command ('get' or 'dump')
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str    
    
    """
    # get and dump are equivalent functionality, just different arguments
    if cmd == 'dump':
        parser = OptionParser(
            usage="usage: %prog dump [options] file [namespace]", prog=NAME)
    elif cmd == 'get':
        parser = OptionParser(usage="usage: %prog get [options] parameter",
                              prog=NAME)
        parser.add_option("-p",
                          dest="pretty",
                          default=False,
                          action="store_true",
                          help="pretty print. WARNING: not YAML-safe")

    parser.add_option("-v",
                      dest="verbose",
                      default=False,
                      action="store_true",
                      help="turn on verbose output")
    options, args = parser.parse_args(argv[2:])

    arg = None
    ns = ''

    if len(args) == 0:
        if cmd == 'dump':
            parser.error("invalid arguments. Please specify a file name")
        elif cmd == 'get':
            parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
    elif len(args) == 2 and cmd == 'dump':
        arg = args[0]
        ns = args[1]
    else:
        parser.error("too many arguments")

    if cmd == 'get':
        _rosparam_cmd_get_param(script_resolve_name(NAME, arg),
                                pretty=options.pretty,
                                verbose=options.verbose)
    else:
        if options.verbose:
            print "dumping namespace [%s] to file [%s]" % (ns, arg)
        dump_params(arg,
                    script_resolve_name(NAME, ns),
                    verbose=options.verbose)
Example #2
0
def _rosparam_cmd_delete(argv):
    """
    Process command line for rosparam delete, e.g.::
      rosparam delete param 
    @param cmd: command name
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str
    """
    parser = OptionParser(usage="usage: %prog delete [options] parameter",
                          prog=NAME)
    parser.add_option("-v",
                      dest="verbose",
                      default=False,
                      action="store_true",
                      help="turn on verbose output")
    options, args = parser.parse_args(argv[2:])

    arg2 = None
    if len(args) == 0:
        parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
    else:
        parser.error("too many arguments")

    delete_param(script_resolve_name(NAME, arg), verbose=options.verbose)
Example #3
0
def rosnode_info(node_name):
    """
    Print information about node, including subscriptions and other debugging information. This will query the node over the network.
    
    @param node_name: name of ROS node
    @type  node_name: str
    @raise ROSNodeIOException: if unable to communicate with master
    """
    def topic_type(t, pub_topics):
        matches = [t_type for t_name, t_type in pub_topics if t_name == t]
        if matches:
            return matches[0]
        return 'unknown type'

    master = scriptutil.get_master()
    node_name = scriptutil.script_resolve_name('rosnode', node_name)

    print('-'*80)
    print(get_node_info_description(node_name))
        
    node_api = get_api_uri(master, node_name)
    if not node_api:
        print("cannot contact [%s]: unknown node"%node_name, file=sys.stderr)
        return
    
    print("\ncontacting node %s ..."%node_api)

    print(get_node_connection_info_description(node_api))
Example #4
0
def rosnode_info(node_name):
    """
    Print information about node, including subscriptions and other debugging information. This will query the node over the network.
    
    @param node_name: name of ROS node
    @type  node_name: str
    @raise ROSNodeIOException: if unable to communicate with master
    """
    def topic_type(t, pub_topics):
        matches = [t_type for t_name, t_type in pub_topics if t_name == t]
        if matches:
            return matches[0]
        return 'unknown type'

    master = scriptutil.get_master()
    node_name = scriptutil.script_resolve_name('rosnode', node_name)

    print '-' * 80
    print get_node_info_description(node_name)

    node_api = get_api_uri(master, node_name)
    if not node_api:
        print >> sys.stderr, "cannot contact [%s]: unknown node" % node_name
        return

    print "\ncontacting node %s ..." % node_api

    print get_node_connection_info_description(node_api)
Example #5
0
def _rosnode_cmd_list(argv):
    """
    Implements rosnode 'list' command.
    """
    args = argv[2:]
    parser = OptionParser(usage="usage: %prog list", prog=NAME)
    parser.add_option("-u",
                      dest="list_uri",
                      default=False,
                      action="store_true",
                      help="list XML-RPC URIs")
    parser.add_option("-a",
                      "--all",
                      dest="list_all",
                      default=False,
                      action="store_true",
                      help="list all information")
    (options, args) = parser.parse_args(args)
    namespace = None
    if len(args) > 1:
        parser.error("invalid args: you may only specify one namespace")
    elif len(args) == 1:
        namespace = scriptutil.script_resolve_name('rostopic', args[0])
    rosnode_listnodes(namespace=namespace,
                      list_uri=options.list_uri,
                      list_all=options.list_all)
Example #6
0
def _rosnode_cmd_kill(argv):
    """
    Implements rosnode 'kill' command.

    @raise ROSNodeException: if user enters in unrecognized nodes
    """
    args = argv[2:]
    parser = OptionParser(usage="usage: %prog kill [node]...", prog=NAME)
    parser.add_option("-a","--all",
                      dest="kill_all", default=False,
                      action="store_true",
                      help="kill all nodes")

    (options, args) = parser.parse_args(args)
    if options.kill_all:
        if args:
            parser.error("invalid arguments with kill all (-a) option")
        args = get_node_names()
        args.sort()
    elif not args:
        node_list = get_node_names()
        node_list.sort()
        if not node_list:
            print("No nodes running", file=sys.stderr)
            return 0
        
        sys.stdout.write('\n'.join(["%s. %s"%(i+1, n) for i,n in enumerate(node_list)]))
        sys.stdout.write("\n\nPlease enter the number of the node you wish to kill.\n> ")
        selection = ''
        while not selection:
            selection = sys.stdin.readline().strip()
            try:
                selection = int(selection) 
                if selection <= 0:
                    print("ERROR: invalid selection. Please enter a number (ctrl-C to cancel)")
            except:
                print("ERROR: please enter a number (ctrl-C to cancel)")
                sys.stdout.flush()
                selection = ''
        args = [node_list[selection - 1]]
    else:
        # validate args
        args = [scriptutil.script_resolve_name(ID, n) for n in args]
        node_list = get_node_names()
        unknown = [n for n in args if not n in node_list]
        if unknown:
            raise ROSNodeException("Unknown node(s):\n"+'\n'.join([" * %s"%n for n in unknown]))
    if len(args) > 1:
        print("killing:\n"+'\n'.join([" * %s"%n for n in args]))
    else:
        print("killing %s"%(args[0]))
            
    success, fail = kill_nodes(args)
    if fail:
        print("ERROR: Failed to kill:\n"+'\n'.join([" * %s"%n for n in fail]), file=sys.stderr)
        return 1
    print("killed")
    return 0
Example #7
0
def _rosparam_cmd_get_dump(cmd, argv):
    """
    Process command line for rosparam get/dump, e.g.::
      rosparam get param
      rosparam dump file.yaml [namespace]
    @param cmd: command ('get' or 'dump')
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str    
    
    """
    # get and dump are equivalent functionality, just different arguments
    if cmd == "dump":
        parser = OptionParser(usage="usage: %prog dump [options] file [namespace]", prog=NAME)
    elif cmd == "get":
        parser = OptionParser(usage="usage: %prog get [options] parameter", prog=NAME)
        parser.add_option(
            "-p", dest="pretty", default=False, action="store_true", help="pretty print. WARNING: not YAML-safe"
        )

    parser.add_option("-v", dest="verbose", default=False, action="store_true", help="turn on verbose output")
    options, args = parser.parse_args(argv[2:])

    arg = None
    ns = ""

    if len(args) == 0:
        if cmd == "dump":
            parser.error("invalid arguments. Please specify a file name")
        elif cmd == "get":
            parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
    elif len(args) == 2 and cmd == "dump":
        arg = args[0]
        ns = args[1]
    else:
        parser.error("too many arguments")

    if cmd == "get":
        _rosparam_cmd_get_param(script_resolve_name(NAME, arg), pretty=options.pretty, verbose=options.verbose)
    else:
        if options.verbose:
            print "dumping namespace [%s] to file [%s]" % (ns, arg)
        dump_params(arg, script_resolve_name(NAME, ns), verbose=options.verbose)
Example #8
0
def _rosnode_cmd_ping(argv):
    """
    Implements rosnode 'ping' command.
    @param argv: command-line args
    @type  argv: [str]
    """
    args = argv[2:]
    parser = OptionParser(usage="usage: %prog ping [options] <node>",
                          prog=NAME)
    parser.add_option("--all",
                      "-a",
                      dest="ping_all",
                      default=False,
                      action="store_true",
                      help="ping all nodes")
    parser.add_option("-c",
                      dest="ping_count",
                      default=None,
                      metavar="COUNT",
                      type="int",
                      help="number of pings to send. Not available with --all")
    (options, args) = parser.parse_args(args)

    node_name = None
    if not options.ping_all:
        if not args:
            try:
                parser.error(
                    "Please enter a node to ping. Available nodes are:\n" +
                    _sub_rosnode_listnodes())
            except:
                # master is offline, but user did have invalid usage, so display correct usage first
                parser.error("Please enter a node to ping")
        elif len(args) > 1:
            parser.error("you may only specify one input node")
        elif len(args) == 1:
            node_name = scriptutil.script_resolve_name('rosnode', args[0])
            print "rosnode: node is [%s]" % node_name
    else:
        if args:
            parser.error("Invalid arguments '%s' used with --all" %
                         (' '.join(args)))
        elif options.ping_count:
            parser.error("-c may not be used with --all")

    if options.ping_all:
        rosnode_ping_all(verbose=True)
    else:
        rosnode_ping(node_name, verbose=True, max_count=options.ping_count)
Example #9
0
def get_node_args(node_name, roslaunch_files):
    """
    Get the node arguments for a node in roslaunch_files. 

    @param node_name: name of node in roslaunch_files.
    @type  node_name: str
    @param roslaunch_files: roslaunch file names
    @type  roslaunch_files: [str]
    @return: list of command-line arguments used to launch node_name
    @rtype: [str]
    @raise RLException: if node args cannot be retrieved
    """
    
    # we have to create our own XmlLoader so that we can use the same
    # resolution context for substitution args

    loader = roslaunch.xmlloader.XmlLoader(resolve_anon=False)
    config = load_config_default(roslaunch_files, None, loader=loader, verbose=False, assign_machines=False)
    (node_name) = roslib.substitution_args.resolve_args((node_name), resolve_anon=False)
    node_name = script_resolve_name('roslaunch', node_name) if not node_name.startswith('$') else node_name
    
    node = [n for n in config.nodes if _resolved_name(n) == node_name] + \
        [n for n in config.tests if _resolved_name(n) == node_name]
    if not node:
        node_list = get_node_list(config)
        node_list_str = '\n'.join([" * %s"%x for x in node_list])
        raise RLException("ERROR: Cannot find node named [%s] in [%s].\nNode names are:\n%s"%(node_name, ', '.join(roslaunch_files), node_list_str))
    elif len(node) > 1:
        raise RLException("ERROR: multiple nodes named [%s] in [%s].\nPlease fix the launch files as duplicate names are not allowed."%(node_name, ', '.join(roslaunch_files)))
    node = node[0]
    
    master_uri = roslib.rosenv.get_master_uri()
    machine = local_machine()

    # don't use create_local_process_env, which merges the env with the full env of the shell
    env = setup_env(node, machine, master_uri)
    to_remove = []
    for k in env.iterkeys():
        if env[k] == os.environ.get(k, None):
            to_remove.append(k)
    for k in to_remove:
        del env[k]

    # resolve node name for generating args
    args = create_local_process_args(node, machine)
    # join environment vars are bash prefix args
    return ["%s=%s"%(k, v) for k, v in env.iteritems()] + args
Example #10
0
def print_node_args(node_name, roslaunch_files):
    """
    Print arguments of node to screen. Will cause system exit if
    exception occurs. This is a subroutine for the roslaunch main
    handler.
    
    @param node_name: node name
    @type  node_name: str
    @param roslaunch_files: list of launch files to load
    @type  roslaunch_files: str
    """
    try:
        node_name = script_resolve_name('roslaunch', node_name)
        args = get_node_args(node_name, roslaunch_files)
        print ' '.join(args)
    except RLException, e:
        print >> sys.stderr, str(e)
        sys.exit(1)
Example #11
0
def _rosparam_cmd_list(argv):
    """
    Process command line for rosparam set/load, e.g.::
      rosparam load file.yaml [namespace]
      rosparam set param value
    @param argv: command-line args
    @type  argv: str
    """
    parser = OptionParser(usage="usage: %prog list [namespace]", prog=NAME)
    options, args = parser.parse_args(argv[2:])

    ns = GLOBALNS
    if len(args) == 1:
        ns = script_resolve_name(NAME, args[0])
    elif len(args) == 2:
        parser.error("too many arguments")

    print "\n".join(list_params(ns))
Example #12
0
def _rosparam_cmd_list(argv):
    """
    Process command line for rosparam set/load, e.g.::
      rosparam load file.yaml [namespace]
      rosparam set param value
    @param argv: command-line args
    @type  argv: str
    """
    parser = OptionParser(usage="usage: %prog list [namespace]", prog=NAME)
    options, args = parser.parse_args(argv[2:])

    ns = GLOBALNS
    if len(args) == 1:
        ns = script_resolve_name(NAME, args[0])
    elif len(args) == 2:
        parser.error("too many arguments")

    print '\n'.join(list_params(ns))
Example #13
0
def print_node_filename(node_name, roslaunch_files):
    try:
        # #2309
        node_name = script_resolve_name('roslaunch', node_name)
        
        loader = roslaunch.xmlloader.XmlLoader(resolve_anon=False)
        config = load_config_default(roslaunch_files, None, loader=loader, verbose=False, assign_machines=False)
        nodes = [n for n in config.nodes if _resolved_name(n) == node_name] + \
            [t for t in config.tests if _resolved_name(t) == node_name]

        if len(nodes) > 1:
            raise RLException("ERROR: multiple nodes named [%s] in [%s].\nPlease fix the launch files as duplicate names are not allowed."%(node_name, ', '.join(roslaunch_files)))
        if not nodes:
            print >> sys.stderr, 'ERROR: cannot find node named [%s]. Run \n\troslaunch --nodes <files>\nto see list of node names.'%(node_name)
        else:
            print nodes[0].filename
        
    except RLException, e:
        print >> sys.stderr, str(e)
        sys.exit(1)
Example #14
0
def _rosnode_cmd_list(argv):
    """
    Implements rosnode 'list' command.
    """
    args = argv[2:]
    parser = OptionParser(usage="usage: %prog list", prog=NAME)
    parser.add_option("-u",
                      dest="list_uri", default=False,
                      action="store_true",
                      help="list XML-RPC URIs")
    parser.add_option("-a","--all",
                      dest="list_all", default=False,
                      action="store_true",
                      help="list all information")
    (options, args) = parser.parse_args(args)
    namespace = None
    if len(args) > 1:
        parser.error("invalid args: you may only specify one namespace")
    elif len(args) == 1:
        namespace = scriptutil.script_resolve_name('rostopic', args[0])
    rosnode_listnodes(namespace=namespace, list_uri=options.list_uri, list_all=options.list_all)
Example #15
0
def _rosnode_cmd_ping(argv):
    """
    Implements rosnode 'ping' command.
    @param argv: command-line args
    @type  argv: [str]
    """
    args = argv[2:]    
    parser = OptionParser(usage="usage: %prog ping [options] <node>", prog=NAME)
    parser.add_option("--all", "-a",
                      dest="ping_all", default=False,
                      action="store_true",
                      help="ping all nodes")
    parser.add_option("-c",
                      dest="ping_count", default=None, metavar="COUNT",type="int",
                      help="number of pings to send. Not available with --all")
    (options, args) = parser.parse_args(args)

    node_name = None
    if not options.ping_all:
        if not args:
            try:
                parser.error("Please enter a node to ping. Available nodes are:\n"+_sub_rosnode_listnodes())
            except:
                # master is offline, but user did have invalid usage, so display correct usage first
                parser.error("Please enter a node to ping")
        elif len(args) > 1:
            parser.error("you may only specify one input node")
        elif len(args) == 1:
            node_name = scriptutil.script_resolve_name('rosnode', args[0])
            print("rosnode: node is [%s]"%node_name)
    else:
        if args:
            parser.error("Invalid arguments '%s' used with --all"%(' '.join(args)))
        elif options.ping_count:
            parser.error("-c may not be used with --all")
            
    if options.ping_all:
        rosnode_ping_all(verbose=True)
    else:
        rosnode_ping(node_name, verbose=True, max_count=options.ping_count)
Example #16
0
def _rosparam_cmd_delete(argv):
    """
    Process command line for rosparam delete, e.g.::
      rosparam delete param 
    @param cmd: command name
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str
    """
    parser = OptionParser(usage="usage: %prog delete [options] parameter", prog=NAME)
    parser.add_option("-v", dest="verbose", default=False, action="store_true", help="turn on verbose output")
    options, args = parser.parse_args(argv[2:])

    arg2 = None
    if len(args) == 0:
        parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
    else:
        parser.error("too many arguments")

    delete_param(script_resolve_name(NAME, arg), verbose=options.verbose)
Example #17
0
def _rosparam_cmd_set_load(cmd, argv):
    """
    Process command line for rosparam set/load, e.g.::
      rosparam load file.yaml [namespace]
      rosparam set param value
    @param cmd: command name
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str    
    """
    if cmd == "load":
        parser = OptionParser(usage="usage: %prog load [options] file [namespace]", prog=NAME)
    elif cmd == "set":
        parser = OptionParser(usage="usage: %prog set [options] parameter value", prog=NAME)
        parser.add_option(
            "-t",
            "--textfile",
            dest="text_file",
            default=None,
            metavar="TEXT_FILE",
            help="set parameters to contents of text file",
        )
        parser.add_option(
            "-b",
            "--binfile",
            dest="bin_file",
            default=None,
            metavar="BINARY_FILE",
            help="set parameters to contents of binary file",
        )

    parser.add_option("-v", dest="verbose", default=False, action="store_true", help="turn on verbose output")
    options, args = _set_optparse_neg_args(parser, argv)
    if cmd == "set":
        if options.text_file and options.bin_file:
            parser.error("you may only specify one of --textfile or --binfile")

    arg2 = None
    if len(args) == 0:
        if cmd == "load":
            parser.error("invalid arguments. Please specify a file name")
        elif cmd == "set":
            parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
        if cmd == "set" and not (options.text_file or options.bin_file):
            parser.error("invalid arguments. Please specify a parameter value")
    elif len(args) == 2:
        arg = args[0]
        arg2 = args[1]
    else:
        parser.error("too many arguments")

    if cmd == "set":
        name = script_resolve_name(NAME, arg)
        # #2647
        if options.text_file:
            if not os.path.isfile(options.text_file):
                parser.error("file '%s' does not exist" % (options.text_file))
            with open(options.text_file) as f:
                arg2 = f.read()
            set_param_raw(name, arg2, verbose=options.verbose)
        elif options.bin_file:
            import xmlrpclib

            with open(options.bin_file, "rb") as f:
                arg2 = xmlrpclib.Binary(f.read())
            set_param_raw(name, arg2, verbose=options.verbose)
        else:
            # #2237: the empty string is really hard to specify on the
            # command-line due to bash quoting rules. We cheat here and
            # let an empty Python string be an empty YAML string (instead
            # of YAML null, which has no meaning to the Parameter Server
            # anyway).
            if arg2 == "":
                arg2 = "!!str"
            set_param(name, arg2, verbose=options.verbose)
    else:
        paramlist = load_file(arg, default_namespace=script_resolve_name(NAME, arg2), verbose=options.verbose)
        for params, ns in paramlist:
            upload_params(ns, params, verbose=options.verbose)
Example #18
0
def _rosparam_cmd_set_load(cmd, argv):
    """
    Process command line for rosparam set/load, e.g.::
      rosparam load file.yaml [namespace]
      rosparam set param value
    @param cmd: command name
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str    
    """
    if cmd == 'load':
        parser = OptionParser(
            usage="usage: %prog load [options] file [namespace]", prog=NAME)
    elif cmd == 'set':
        parser = OptionParser(
            usage="usage: %prog set [options] parameter value", prog=NAME)
        parser.add_option("-t",
                          "--textfile",
                          dest="text_file",
                          default=None,
                          metavar="TEXT_FILE",
                          help="set parameters to contents of text file")
        parser.add_option("-b",
                          "--binfile",
                          dest="bin_file",
                          default=None,
                          metavar="BINARY_FILE",
                          help="set parameters to contents of binary file")

    parser.add_option("-v",
                      dest="verbose",
                      default=False,
                      action="store_true",
                      help="turn on verbose output")
    options, args = _set_optparse_neg_args(parser, argv)
    if cmd == 'set':
        if options.text_file and options.bin_file:
            parser.error("you may only specify one of --textfile or --binfile")

    arg2 = None
    if len(args) == 0:
        if cmd == 'load':
            parser.error("invalid arguments. Please specify a file name")
        elif cmd == 'set':
            parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
        if cmd == 'set' and not (options.text_file or options.bin_file):
            parser.error("invalid arguments. Please specify a parameter value")
    elif len(args) == 2:
        arg = args[0]
        arg2 = args[1]
    else:
        parser.error("too many arguments")

    if cmd == 'set':
        name = script_resolve_name(NAME, arg)
        # #2647
        if options.text_file:
            if not os.path.isfile(options.text_file):
                parser.error("file '%s' does not exist" % (options.text_file))
            with open(options.text_file) as f:
                arg2 = f.read()
            set_param_raw(name, arg2, verbose=options.verbose)
        elif options.bin_file:
            import xmlrpclib
            with open(options.bin_file, 'rb') as f:
                arg2 = xmlrpclib.Binary(f.read())
            set_param_raw(name, arg2, verbose=options.verbose)
        else:
            # #2237: the empty string is really hard to specify on the
            # command-line due to bash quoting rules. We cheat here and
            # let an empty Python string be an empty YAML string (instead
            # of YAML null, which has no meaning to the Parameter Server
            # anyway).
            if arg2 == '':
                arg2 = '!!str'
            set_param(name, arg2, verbose=options.verbose)
    else:
        paramlist = load_file(arg,
                              default_namespace=script_resolve_name(
                                  NAME, arg2),
                              verbose=options.verbose)
        for params, ns in paramlist:
            upload_params(ns, params, verbose=options.verbose)
Example #19
0
def _rosparam_cmd_set_load(cmd, argv):
    """
    Process command line for rosparam set/load, e.g.::
      rosparam load file.yaml [namespace]
      rosparam set param value
    @param cmd: command name
    @type  cmd: str
    @param argv: command-line args
    @type  argv: str    
    """
    if cmd == 'load':
        parser = OptionParser(usage="usage: %prog load [options] file [namespace]", prog=NAME)
    elif cmd == 'set':
        parser = OptionParser(usage="usage: %prog set [options] parameter value", prog=NAME)

    parser.add_option("-v", dest="verbose", default=False,
                      action="store_true", help="turn on verbose output")
    
    # we don't use optparse to parse actual arguments, just options,
    # due to the fact that optparse doesn't handle negative numbers as
    # arguments.
    args = []
    optparse_args = []
    for s in argv[2:]:
        if s.startswith('-'):
            if len(s) > 1 and ord(s[1]) >= ord('0') and ord(s[1]) <= ord('9'):
                args.append(s)
            else:
                optparse_args.append(s)
        else:
            args.append(s)
    options, _ = parser.parse_args(optparse_args)

    arg2 = None
    if len(args) == 0:
        if cmd == 'load':
            parser.error("invalid arguments. Please specify a file name")
        elif cmd == 'set':
            parser.error("invalid arguments. Please specify a parameter name")
    elif len(args) == 1:
        arg = args[0]
        if cmd == 'set':
            parser.error("invalid arguments. Please specify a parameter value")
    elif len(args) == 2:
        arg = args[0]
        arg2 = args[1]
    else:
        parser.error("too many arguments")

    if cmd == 'set':
        # #2237: the empty string is really hard to specify on the
        # command-line due to bash quoting rules. We cheat here and
        # let an empty Python string be an empty YAML string (instead
        # of YAML null, which has no meaning to the Parameter Server
        # anyway).
        if arg2 == '':
            arg2 = '!!str'
        set_param(script_resolve_name(NAME, arg), arg2, verbose=options.verbose)
    else:
        paramlist = load_file(arg, default_namespace=script_resolve_name(NAME, arg2), verbose=options.verbose)
        for params,ns in paramlist:
            upload_params(ns, params, verbose=options.verbose)